【问题标题】:How to find missing date and shift in MySQL?如何在 MySQL 中查找丢失的日期和班次?
【发布时间】:2017-11-06 05:56:00
【问题描述】:

我的 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 个日期。 请帮帮我。

【问题讨论】:

  • 包括你已经启动的php和查询
  • SQL 在这里帮不了你。它可以从数据库中提取数据,但只能提取已经在数据库中的数据。
  • 您是如何发现这些记录丢失的?是否有关于每个日期应该有 3 个班次或有另一个班次表的规范/约定?
  • @Beginner 我只使用 mysql 而不是 php

标签: mysql sql database database-administration


【解决方案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


更新:

您在 cmets 中的问题可以这样回答:

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

【讨论】:

  • 你的问题不清楚!添加该条件后,它有许多与您期望的结果相关的答案;)。
  • 我想在表中添加id并根据id条件查找
  • 我建议你在另一个问题中问它;提供一些示例数据 - 有一个 id - 以及您的预期结果 - 添加该条件后 - HTH ;)。
  • 您的查询不返回2017-01-01 的第一个班次的结果,它在 51 id 中也丢失了
  • 答案是正确的,但不是我的问题。请帮帮我
猜你喜欢
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多