Как выбрать просроченные строки с частотами дат? - PullRequest
2 голосов
/ 20 января 2020
+------------------------+--------+
|  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

Ответы [ 4 ]

2 голосов
/ 20 января 2020

1 Чтобы добиться этого, нужно сгенерировать диапазон дат с разницей в 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 строк. Если ваша таблица слишком велика, вы можете сгенерировать 10000 строк, используя еще 1 перекрестное соединение.

1 голос
/ 29 января 2020
WHERE (DATEDIFF(due_date, CURDATE) % 5) = 0

Он выберет все кратные 5 до и после сегодняшнего дня ...

1 голос
/ 20 января 2020

Если вы используете 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
1 голос
/ 20 января 2020

Вы можете создать переменную и передать ее в подготовленный оператор, как показано ниже.

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;

При условии, что вы передадите 5 для @dateinterval, приведенный выше оператор будет разрешен как:

 SELECT * FROM `invoices`
 WHERE `due_date` IN (
 (CURDATE() + INTERVAL 5 day),
 (CURDATE() + INTERVAL 10 day),
 (CURDATE() + INTERVAL 15 day)
 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...