对于mysql,为什么这个日期查询显示不正确的结果?

ttvkxqim  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(317)

样品表:

id | foreign_key_id | timestamp           | amt |
-------------------------------------------------
1  | 223344         | 2018-06-01 09:22:31 | 3
2  | 233445         | 2018-06-15 23:22:31 | 2
2  | 233445         | 2018-06-30 23:22:31 | 5
3  | 334455         | 2018-07-01 12:22:31 | 1
3  | 334455         | 2018-07-15 12:22:31 | 1
4  | 344556         | 2018-07-31 20:22:31 | 2

我想要的是一个 amt 每个月,大概,

year | month | total_amt
------------------------
2018 |     6 |       10
2018 |     7 |        4

我认为用这样的查询很容易实现,

SELECT YEAR(timestamp) year, MONTH(timestamp) month, SUM(amt) total_amt
FROM sample_table
WHERE timestamp >= '2018-06-01'
AND timestamp <= '2018-07-31'
GROUP BY YEAR(timestamp), MONTH(timestamp)

很遗憾,这个查询的结果不正确,

year | month | total_amt
------------------------
2018 |     6 |       10
2018 |     7 |        2

六月份的数额是正确的,但七月份是错误的。

lx0bsm1f

lx0bsm1f1#

这将起作用:

SELECT YEAR(timestamp) year, MONTH(timestamp) month, SUM(amt) total_amt
FROM sample_table
WHERE DATE(timestamp) >= '2018-06-01'
AND DATE(timestamp) <= '2018-08-01'
GROUP BY YEAR(timestamp), MONTH(timestamp);

SELECT YEAR(timestamp) year, MONTH(timestamp) month, SUM(amt) total_amt
FROM sample_table
WHERE DATE(timestamp) BETWEEN '2018-06-01' AND '2018-08-01'
GROUP BY YEAR(timestamp), MONTH(timestamp);
9q78igpj

9q78igpj2#

试试这个:

SELECT YEAR(timestamp) year, MONTH(timestamp) month, SUM(amt) total_amt
FROM sample_table
WHERE timestamp >= '2018-06-01'
AND timestamp < '2018-08-01'
GROUP BY YEAR(timestamp), MONTH(timestamp)
jgovgodb

jgovgodb3#

这是对时间戳的误解,然后是比较字符串。
时间戳中有一个日期时间对象,它既有日期部分,也有时间部分。查询中使用的字符串只是日期部分,没有时间部分,所以当mysql执行它的操作时,它基本上“清零”了剩余的日期。
所以当查询

...
AND timestamp <= '2018-07-31'

基本上变成了,

...
AND timestamp <= '2018-07-31 00:00:00'

当您转储与查询不匹配的行时,

...
AND '2018-07-31 20:22:31' <= '2018-07-31 00:00:00'

无论是日期比较,甚至是简单的字符串比较,丢失行的时间戳都不小于或等于传入的日期,它肯定更大。
你有几个选项来解决这个问题,在比较中创建一个完整的日期时间对象,其中包含“最完整”的时间,

...
AND timestamp <= '2018-07-31 23:59:59'

将运算符更改为小于下一个日期,

...
AND timestamp < '2018-08-01'

或者将时间戳从日期时间对象转换为日期时间对象,

...
AND DATE(timestamp) <= '2018-07-31'

所有的工作,但我不知道哪一个是最好的性能/速度方面。

相关问题