【问题标题】:Problem in getting records from last 13 months in MySQL在 MySQL 中获取过去 13 个月的记录时出现问题
【发布时间】:2020-03-07 15:03:48
【问题描述】:

我正在使用以下 MySQL 查询获取过去 13 个月的记录:

SELECT YEAR(`customer_date`),
       MONTHNAME(`customer_date`),
       COUNT(`customer_date`) AS Enquiries
FROM   `crm_customers`
WHERE  DATE(`customer_date`) BETWEEN CURRENT_DATE - INTERVAL 13 month AND
                                     CURRENT_DATE
GROUP  BY YEAR(`customer_date`),
          MONTH(`customer_date`)
ORDER  BY YEAR(`customer_date`) DESC,
          MONTH(`customer_date`) DESC  

我的原型 MySQL 表 crm_customers 看起来像:

customer_id    customer_date
1              2019-02-01 00:00:00
2              2019-02-02 00:00:00
...            ...
...            ...
...            ...

输出:

虽然上面的查询确实可以正常工作,并且给了我几乎正确的结果集,除了一个与去年最后一个月相关的问题,距今天 13 个月的差距。

今天是 2020 年 3 月 7 日。我上面查询中的日期条件

WHERE  DATE(`customer_date`) BETWEEN CURRENT_DATE - INTERVAL 13 month AND CURRENT_DATE

从 2019 年 2 月 7 日开始获取结果。

在 2019 年 2 月,我有 104 个条目。但我上面的 SQL 仅获取 80 个条目,因为 24 个条目在 2019 年 2 月 7 日之前(2019 年 2 月 1 日至 2 月 6 日之间)。我也想包括这些条目。如何修改我的日期条件以达到所需的结果。

编辑

为什么这个问题被标记为否定?我不明白。问题非常清楚,没有重复。是被 GMB 否决了吗?

【问题讨论】:

  • 你期望什么?数据之间的当前月份(2020-02)到 13 个月(2019-02)?或当前日期(2020-02-07)到 13 个月前的日期(2019-02-07)?
  • @Tushar 2019-02-01 到 2020-03-07 之间的数据

标签: mysql sql date where-clause


【解决方案1】:

将您的 WHERE 子句更改为:

WHERE  DATE(`customer_date`) BETWEEN DATE_FORMAT(NOW() ,'%Y-%m-01') - INTERVAL 13 month AND DATE_FORMAT(NOW() ,'%Y-%m-01')

【讨论】:

    【解决方案2】:

    有一些可能实现这一点

    SELECT CURDATE()
    , CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE)
    ,LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY;
    

    结果

    CURDATE() , CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE), LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY
    2020-03-07, 2020-03-01                                  , 2020-03-01
    

    【讨论】:

      【解决方案3】:

      听起来您想降低 DATE 值的精度。为此使用EXTRACT()

      EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL 13 MONTH)
      

      【讨论】:

      • 这没有给我正确的输出。它从 2017 年 1 月获取结果集。我只想获取过去 13 个月前到今天的数据。
      【解决方案4】:

      我建议:

      where 
          customer_date >= date_format(current_date, '%Y-%m-01') - interval 13 month
          and customer_date < current_date + interval 1 day
      

      理由:

      • 这会比较存储的日期而无需事先转换(而您的查询和到目前为止的所有答案都使用date()),这可以使现有索引受益 - 在大型数据集上,这可以使性能差异很大

      • 日期算术尽可能简单; MySQL 很乐意将适当格式的字符串视为日期,这可以缩短语法

      【讨论】:

      • 虽然您的查询工作正常,但我不需要在current_date + interval 1 day 多花一天时间。相反,我想将直到今天的记录返回到 13 个月。
      • MySQL 保留关键字也不要使用小写。使用大写例如CURRENT_DATE、INTERVAL 等,有助于轻松阅读和理解查询。
      • @Sachin:那么您可以将customer_date &lt; current_date + interval 1 day 更改为customer_date &lt; current_date。大写/小写是个人喜好问题,您可以随意更改。为什么我回答是因为我相信这个解决方案比其他解决方案更有效,因为日期上的 SARGable 过滤器(即可以利用索引)。
      • 我不认为这只是品味或个人喜好的问题。相信我,如果您按照编码专家的建议使用正确的变量/关键字/函数命名约定,那么即使乍一看,它们肯定会提高编码的可读性和理解力。当您写current_date 并且我第一眼看到它时,我才意识到它可能是您的自定义别名。但是当我写CURRENT_DATE的时候,看过我问题的人都清楚地知道,它一定是MySQL为日期部分保留的关键字/函数。我希望你能理解我的逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多