能否通过JOIN在SQL查询中创建两个COUNT()列:分别统计两表共存数据与单表独存数据
当然可以实现!
你完全可以通过LEFT JOIN配合条件判断和COUNT()来同时生成这两个统计列,不需要拆分两次查询。下面结合你给出的示例数据来具体说明:
核心思路
用tbl_a LEFT JOIN tbl_b ON tbl_a.trans_id = tbl_b.trans_id关联两张表,这样tbl_a里的所有行都会被保留,而tbl_b中匹配不到的行,对应字段会是NULL。我们可以利用COUNT()忽略NULL值的特性,分别统计匹配成功和匹配失败的行数。
具体SQL语句
SELECT COUNT(tbl_b.trans_id) AS in_a_and_b, COUNT(CASE WHEN tbl_b.trans_id IS NULL THEN 1 END) AS not_in_b FROM tbl_a LEFT JOIN tbl_b ON tbl_a.trans_id = tbl_b.trans_id;
结果逻辑解释
COUNT(tbl_b.trans_id):只有当tbl_b中存在匹配的trans_id时,这个字段才不为NULL,所以统计的就是同时存在于两张表的行数(对应示例里的2)。COUNT(CASE WHEN tbl_b.trans_id IS NULL THEN 1 END):当tbl_b没有匹配项时,CASE语句返回1,否则返回NULL,COUNT会只统计这些有效的1,也就是仅在tbl_a存在的行数(对应示例里的1)。
另一种等价写法(用SUM替代COUNT)
如果你更习惯用SUM(),也可以写成下面这样,逻辑完全一致:
SELECT SUM(CASE WHEN tbl_b.trans_id IS NOT NULL THEN 1 ELSE 0 END) AS in_a_and_b, SUM(CASE WHEN tbl_b.trans_id IS NULL THEN 1 ELSE 0 END) AS not_in_b FROM tbl_a LEFT JOIN tbl_b ON tbl_a.trans_id = tbl_b.trans_id;
以上两种写法都能得到你期望的输出结果:
| in_a_and_b | not_in_b |
|---|---|
| 2 | 1 |
内容的提问来源于stack exchange,提问作者Daniel Catalan
相关产品推荐
相关产品推荐

