【问题标题】:How to select Overdue Rows with Date Frequencies?如何选择具有日期频率的过期行?
【发布时间】:2020-05-06 04:07:09
【问题描述】:
+------------------------+--------+
|  Invoice_id | due_date | amount |
+-------------+----------+--------+
|  20         |2020-01-18|  1250  |
+-------------+----------+--------+
| 21          |2020-01-15|  1335  |
+-------------+----------+--------+

获取所有日期已过的记录n days and its multiple serires 如下...

例如 n=5

SELECT * FROM `invoices` 
WHERE `due_date = DATE_ADD(CURDATE() + INTERVAL 5 days)
OR due_date = DATE_ADD(CURDATE() + INTERVAL 10 days)
OR due_date = DATE_ADD(CURDATE() + INTERVAL 15 days)`

但我想让它适用于任何n value

【问题讨论】:

    标签: mysql database date where-clause


    【解决方案1】:
    WHERE (DATEDIFF(due_date, CURDATE) % 5) = 0
    

    它会选择今天前后所有5的倍数...

    【讨论】:

      【解决方案2】:

      如果您使用的是 MySQL 8.0 或更高版本,这里有另一种选择 -

      WITH  CTE (RN, ID, DUE_DATE, AMT) AS(
      SELECT *, ROW_NUMBER() OVER(ORDER BY due_date) RN FROM Invoices
      WHERE due_date >=CURDATE()
      )
      SELECT * FROM CTE WHERE RN%5=0
      

      【讨论】:

      • 不错的答案...但是一些服务器正在托管 mysql 版本 8.0 以上
      【解决方案3】:

      实现此目的的一种方法是生成一个相差 5 天的日期范围,然后将其与您的表格连接 -

      SELECT *
      FROM `invoices` I
      JOIN (SELECT a.Date
            FROM (SELECT CURDATE() + INTERVAL (a.a + (10 * b.a) + (100 * c.a) ) * 5 DAY as Date
                  FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
                  CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) as b
                  CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) as c
                 )a
            WHERE a.Date <= (SELECT MAX(due_date) FROM `invoices`)
           ) ON I.due_date = a.Date
      

      我在这里只生成了 1000 行。如果您的表太大,那么您可能会使用另外 1 个交叉连接生成 10000 行。

      【讨论】:

        【解决方案4】:

        您可以创建一个变量并将其传递给一个准备好的语句,如下所示。

        SET @dateinterval = n;
        
        SET @preparedStatement = CONCAT("
        SELECT * FROM `invoices`
        WHERE `due_date` IN (
        (CURDATE() + INTERVAL ",@dateinterval," day),
        (CURDATE() + INTERVAL ",@dateinterval*2," day),
        (CURDATE() + INTERVAL ",@dateinterval*3," day)
        );
        ");
        
        PREPARE SQLStatement FROM @preparedStatement;
        EXECUTE SQLStatement;
        DEALLOCATE PREPARE SQLStatement;
        

        如果@dateinterval 传入5,上述语句将解析为:

         SELECT * FROM `invoices`
         WHERE `due_date` IN (
         (CURDATE() + INTERVAL 5 day),
         (CURDATE() + INTERVAL 10 day),
         (CURDATE() + INTERVAL 15 day)
         );
        

        【讨论】:

        • INTERVAL 150 天怎么样?你会写30个条件吗?
        • 我认为 OP 正在尝试开发一些动态查询,该查询可以接受任何 x 天的传递并返回带有 x 乘数的结果。我的回答是基于 OP 的问题。
        • 但重点是,OP 不仅限于仅选择 3 行。他可能想要达到 100 条记录。那时不可能写出那些条件。
        猜你喜欢
        • 2021-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-22
        • 2015-06-21
        • 2019-01-23
        相关资源
        最近更新 更多