比较两个 MYSQL 表并按列返回缺失的日期和分组

Posted

技术标签:

【中文标题】比较两个 MYSQL 表并按列返回缺失的日期和分组【英文标题】:Compare two MYSQL tables and return missing dates and group by column 【发布时间】:2020-12-12 13:37:41 【问题描述】:

我有两张桌子。我想将表 A 与 B 进行比较,并从用户名中获取缺失的日期。

表 A

|----|----------|------------|
| 1  | king     | 2020-08-01 |
| 2  | king     | 2020-08-02 |
| 3  | queen    | 2020-08-01 |
| 4  | queen    | 2020-08-02 |
| 5  | rook     | 2020-08-03 |
| 6  | bishop   | 2020-08-01 |
| 7  | bishop   | 2020-08-01 |
| 8  | queen    | 2020-08-03 |

表 B

| id | working_date |
|----|--------------|
| 1  | 2020-08-01   |
| 2  | 2020-08-02   |
| 3  | 2020-08-03   |

预期输出

| name   | missing_date |
|--------|--------------|
| king   | 2020-08-03   |
| rook   | 2020-08-01   |
| rook   | 2020-08-02   |
| bishop | 2020-08-02   |
| bishop | 2020-08-03   |

此外,如果可能的话,我能否获得每个用户的count缺失日期?

【问题讨论】:

【参考方案1】:

从表 A 中获取不同的用户名并将其与表 B 连接,您可以创建用户的所有工作日期变体。然后不存在您可以列出缺少的日期:

SELECT A1.name, B.working_date
FROM B JOIN
  (SELECT DISTINCT name
   FROM A) A1
WHERE NOT EXISTS (
  SELECT *
  FROM A
  WHERE A.name = A1.name
    and A.working_date = B.working_date
)

对于查找缺失计数的最后一个问题,您可以使用以下查询:

SELECT S.name, COUNT(1) AS 'MissingDatesCount'
FROM (
    SELECT A1.name, B.working_date
    FROM B JOIN
      (SELECT DISTINCT name
       FROM A) A1
    WHERE NOT EXISTS (
      SELECT *
      FROM A
      WHERE A.name = A1.name
        and A.working_date = B.working_date
    )
) S
GROUP BY S.name

转到SqlFiddle

【讨论】:

没有 ON 子句的 INNER 连接是 CROSS 连接。 @forpas 感谢您的解释,这才是真正的目标。【参考方案2】:

您必须将表 B 交叉连接到表 A 的不同名称,然后左连接表 A 以过滤掉匹配的行:

select n.name, b.working_date missing_date 
from TableB b
cross join (select distinct name from TableA) n
left join TableA a on a.name = n.name and a.working_date = b.working_date
where a.id is null

如果您想计算missing_dates,请使用相同的查询并按名称分组:

select n.name, count(*) missing_dates 
from TableB b
cross join (select distinct name from TableA) n
left join TableA a on a.name = n.name and a.working_date = b.working_date
where a.id is null
group by n.name

请参阅demo。 结果:

> name   | missing_date
> :----- | :-----------
> king   | 2020-08-03  
> rook   | 2020-08-01  
> rook   | 2020-08-02  
> bishop | 2020-08-02  
> bishop | 2020-08-03 

和:

> name   | missing_dates
> :----- | ------------:
> bishop |             2
> king   |             1
> rook   |             2

【讨论】:

谢谢 :) ,这很有帮助。但是我可以将这两个查询都作为一个表吗? 你的mysql是什么版本的? 那么你就不能使用8.0版本中引入的窗口函数所以只有加入这2个查询才能得到你想要的:dbfiddle.uk/… MySql 8.0 的解决方案很简单:dbfiddle.uk/…

以上是关于比较两个 MYSQL 表并按列返回缺失的日期和分组的主要内容,如果未能解决你的问题,请参考以下文章

比较两个 SQL 表并返回缺失的 id?

如何对每个表进行分组计数并按列打印? [复制]

如何基于 ManyToManyField 内部连接表并按参数分组并在 Django 中获取最新的表?

按列分组,结果限制并按另一列轨道排序

Python - 读取 csv 并按列对数据进行分组

Python - 导入csv文件并按列分组数字