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

Compare two MYSQL tables and return missing dates and group by column

我有两个 table。我想比较 table A 和 B 并从用户名中获取缺失的日期。

TABLE一个

|----|----------|------------|
| 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 |

TABLE 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 吗?

您必须将 Table B 交叉连接到 Table A 的不同名称,然后左连接 Table 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

从 Table A 获取不同的用户名并将其与 Table 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