代码之家  ›  专栏  ›  技术社区  ›  seaders

对于MySQL,为什么这个日期查询显示错误的结果?

  •  0
  • seaders  · 技术社区  · 7 年前

    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
    

    3 回复  |  直到 7 年前
        1
  •  2
  •   seaders    7 年前

    这是什么误会 比较的字符串。

    在timestamp中是一个日期时间对象,它既有日期部分,又有时间部分。查询中使用的字符串是 只是

    所以当查询是

    ...
    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'
    

    所有的工作,虽然我不确定哪一个性能/速度最好。

        2
  •  1
  •   Fahmi    7 年前

    试试这个:

    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)
    
        3
  •  1
  •   Strawberry    7 年前

    这将起作用:

    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);