比较两个 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 表并按列返回缺失的日期和分组的主要内容,如果未能解决你的问题,请参考以下文章