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

问题描述 投票:-2回答:1

我的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第二班,2017-01-03第三班。和2017-01-04的日期已经完全错过所以如何通过MySQL查询找到这个?我想条件找到id ='51'然后结果是第一班也在2017-01-01中丢失,并且还发现错过了27天并且显示了27个日期。请帮我。

mysql sql database database-administration
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.