如何在MySQL中找到丢失的日期和班次?

时间:2017-11-06 05:56:00

标签: mysql sql database database-administration

我的MySQL表中有三列:

id   | date       | shift  
-----+------------+---------
52   | 2017-01-01 | 1
51   | 2017-01-01 | 2
51   | 2017-01-01 | 3
51   | 2017-01-02 | 1
51   | 2017-01-02 | 3
51   | 2017-01-03 | 1
51   | 2017-01-03 | 2
51   | 2017-01-05 | 1
51   | 2017-01-05 | 2
51   | 2017-01-05 | 3

在此表中缺少两个班次; 2017-01-02的第2班和2017-01-03的第3班。和2017-01-04的日期已经完全错过所以如何通过MySQL查询找到这个? 我想条件找到id =' 51' 然后结果是2017-01-01中也缺少第一班 并且还发现错过了27天并显示27个日期。 请帮帮我。

1 个答案:

答案 0 :(得分:1)

一种方法是制作所有可接受的行,然后像这样过滤当前行:

select *
from (
    select `date`
    from `yourTable`
    group by `date`) as `td`     -- gathering unique data
cross join (
    select 1 `shift`
    union all select 2
    union all select 3) as `ts`  -- generating a source for shifts
-- filtering those are not exists in current rows
where not exists (
    select 1 from `yourTable` as `ti`
    where `ti`.`date` = `td`.`date` and `ti`.`shift` = `ts`.`shift`);

MySQL Fiddle Demo

更新:

在评论中回答你的问题可以是:

select *
from (
  select *
  from (
      select `id`, `date`          -- <= added `id`
      from `yourTable`
      group by `id`, `date`) as `td`     -- gathering unique data <= added `id`
  cross join (
      select 1 `shift`
      union all select 2
      union all select 3) as `ts`  -- generating a source for shifts
  where not exists (
      select 1 from `yourTable` as `ti`
      -- filtering those are not exists in current rows
      where `ti`.`date` = `td`.`date` 
        and `ti`.`id` = `td`.`id`  -- <= added `id` filter
        and `ti`.`shift` = `ts`.`shift`)
  ) as `t`
where `id` = 51;      -- <= now you can filter over its result

MySQL Fiddle Demo

更新:
当你再次改变你的问题时:

select *
from (
  select *
  from (
      select a.Date 
      from (
          select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) 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 between '2017-01-01' and '2017-01-04'
       ) as `td`     -- gathering unique data
  cross join (
      select 1 `shift`
      union all select 2
      union all select 3) as `ts`  -- generating a source for shifts
  where not exists (
      select 1 from `yourTable` as `ti`
      -- filtering those are not exists in current rows
      where `ti`.`date` = `td`.`date` 
        and `ti`.`id` = 51
        and `ti`.`shift` = `ts`.`shift`)
  ) as `t`;

MySQL Fiddle Demo