计算T2中各ClientId下仅存在于T2的ItemId数量(与T1对比)
问题描述
有两个结构完全一致的表T1和T2,均包含ClientId和ItemId列。需要计算:针对T2中的每一个ClientId,统计仅存在于T2、且不存在于T1同ClientId下的ItemId数量。
示例数据
T1表
| ClientId | ItemId |
|---|---|
| 1 | 11 |
| 2 | 21 |
| 2 | 22 |
| 2 | 23 |
T2表
| ClientId | ItemId |
|---|---|
| 2 | 22 |
| 2 | 23 |
| 2 | 24 |
| 2 | 25 |
| 3 | 31 |
预期输出
| ClientId | ItemIdCount |
|---|---|
| 2 | 2 |
| 3 | 1 |
说明
T2中ClientId=2的ItemId有22、23、24、25,其中22、23在T1的同ClientId下存在,因此统计结果为2;ClientId=3在T1中无对应记录,所以所有ItemId都计入统计,结果为1。
解决方案
方法1:LEFT JOIN + COUNT
通过左连接T1表,筛选出T2中无法匹配到T1同ClientId+ItemId的记录,再按ClientId分组统计数量:
SELECT t2.ClientId, COUNT(t2.ItemId) AS ItemIdCount FROM T2 LEFT JOIN T1 ON t2.ClientId = t1.ClientId AND t2.ItemId = t1.ItemId WHERE t1.ClientId IS NULL GROUP BY t2.ClientId;
逻辑解释:左连接保留T2所有记录,当T1中没有相同ClientId和ItemId的匹配项时,T1的字段会为NULL,通过WHERE t1.ClientId IS NULL筛选出这些仅在T2存在的记录,最后分组计数。
方法2:NOT EXISTS子查询
利用NOT EXISTS判断当前T2的记录是否在T1中存在,再分组统计:
SELECT ClientId, COUNT(ItemId) AS ItemIdCount FROM T2 WHERE NOT EXISTS ( SELECT 1 FROM T1 WHERE T1.ClientId = T2.ClientId AND T1.ItemId = T2.ItemId ) GROUP BY ClientId;
逻辑解释:子查询检查T1中是否有相同ClientId和ItemId的记录,NOT EXISTS会筛选出T2中不存在于T1的记录,之后分组计数。
方法3:EXCEPT + 分组统计
先通过EXCEPT获取T2独有的(ClientId, ItemId)组合,再按ClientId分组计数:
SELECT ClientId, COUNT(ItemId) AS ItemIdCount FROM ( SELECT ClientId, ItemId FROM T2 EXCEPT SELECT ClientId, ItemId FROM T1 ) AS T2_Only GROUP BY ClientId;
逻辑解释:EXCEPT会返回T2中存在但T1中不存在的(ClientId, ItemId)唯一组合,外层查询对这些结果分组统计数量。
内容的提问来源于stack exchange,提问作者havij
相关产品推荐
相关产品推荐

