查找每个产品的缺失日期,其中多个产品存储在同一个表中

时间:2021-04-01 12:43:39

标签: mysql sql mysql-5.7

我有一个与此类似的表结构,它每天跟踪一些产品数据:

product_id|columnA|columnB|my_date|
   1      |  a1   |  a2   |2021-03-03|
   1      |  a1   |  a2   |2021-03-04|
   1      |  a1   |  a2   |2021-03-06|
   1      |  a1   |  a2   |2021-03-07|
   1      |  a1   |  a2   |2021-03-10|
   2      |  a1   |  a2   |2021-06-01|
   2      |  a1   |  a2   |2021-06-03|
  ...
 (more product_id)

如您所见,|2021-03-05| 1 缺少 |2021-03-08||2021-03-09|product_id|2021-06-02| 缺少 product_id 2.

我想获取每个 product_id 的所有缺失日期,结果表应如下所示:

product_id|mssing_date|
   1      |2021-03-05|
   1      |2021-03-08|
   1      |2021-03-09|
   2      |2021-06-02|
  ...          ....
other_ids |other_missing dates|

2 个答案:

答案 0 :(得分:0)

使用 cross join 概括产品和日期的所有组合。然后删除它们。 . .一种方法是左连接:

select p.product_id, d.my_date
from (select distinct product_id from t) p cross join
     (select distinct my_date from t) d left join
     t
     on t.product_id = p.product_id and t.my_date = p.my_date
where t.product_id is null;

编辑:

对于修改后的问题(基于评论),您只需计算日期范围并将其用于查询:

select p.product_id, d.my_date
from (select product_id, min(my_date) as min_my_date, max(my_date) as max_my_date
      from t
      group by product_id
     ) p join
     (select distinct my_date from t) d
     on d.my_date bewteen p.min_my_date and p.max_my_date left join
     t
     on t.product_id = p.product_id and
        t.my_date = p.my_date
where t.product_id is null;

这些方法假设数据中的每个日期至少有一行。否则,您需要一种不同的方式来生成日期,例如日历表或递归 CTE。

答案 1 :(得分:0)

WITH RECURSIVE all_dates AS (
   SELECT '2021-01-01' AS d_date
 UNION
   SELECT d_date + INTERVAL 1 DAY
   FROM all_dates
   WHERE d_date < '2021-12-31')
SELECT product_id, d_date
FROM all_dates
LEFT JOIN products ON d_date = product.date
WHERE product.date IS NULL;

使用 MySQL 8

https://dba.stackexchange.com/questions/224182/generate-dates-between-date-ranges-in-mysql