我正在尝试在SQL中编写一个聚合查询,它返回连接到表中给定记录的所有记录的计数;如果没有记录加入给定记录,则该记录的结果应为0
:
我的数据库看起来像这样(遗憾的是我无法更改结构):
MESSAGE
----------------------------------------------
MESSAGEID SENDER SUBJECT
----------------------------------------------
1 Tim Rabbit of Caerbannog
2 Bridgekeeper Bridge of Death
MESSAGEPART
----------------------------------------------
MESSAGEID PARTNO CONTENT
----------------------------------------------
1 0 (BLOB)
1 1 (BLOB)
3 0 (BLOB)
(MESSAGEPART
有一个复合PRIMARY KEY("MESSAGEID", "PARTNO")
)
鉴于上述数据,我应该得到这样的结论:
MESSAGEID COUNT(*)
-----------------------------------------------
1 2
2 0
很明显,我需要在MESSAGE
表上执行左连接,但如何为0
中已连接列的行返回MESSAGEPART
的计数{ {1}}?我尝试了以下内容:
我试过
NULL
然而,这会返回
SELECT m.MESSAGEID, COUNT(*) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY m.MESSAGEID;
我也试过
MESSAGEID COUNT(*)
-----------------------------------------------
1 2
2 1
但是会返回
SELECT mp.MESSAGEID, COUNT(*) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY mp.MESSAGEID;
我在这里做错了什么?
答案 0 :(得分:46)
这样的事情怎么样:
SELECT m.MESSAGEID, sum((case when mp.messageid is not null then 1 else 0 end)) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY m.MESSAGEID;
COUNT()函数将计算每一行,即使它为null。使用SUM()和CASE,您只能计算非空值。
编辑:从最高评论中采用的更简单的版本:
SELECT m.MESSAGEID, COUNT(mp.MESSAGEID) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY m.MESSAGEID;
希望有所帮助。
答案 1 :(得分:9)
你首先想要在加入之前计算你的messaepart表,我想。试试这个:
SELECT m.MessageId
, COALESCE(c, 0) as myCount
FROM MESSAGE m
LEFT JOIN (SELECT MESSAGEID
, count(*) c
FROM MESSAGEPART
GROUP BY MESSAGEID) mp
ON mp.MESSAGEID = m.MESSAGEID
答案 2 :(得分:0)
别忘了使用 DISTINCT ,以防您左联接多个表:
SELECT m.MESSAGEID, COUNT(DISTINCT mp.MESSAGEID) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY m.MESSAGEID;
答案 3 :(得分:0)
根据匹配的列返回一个数字作为两个表之间匹配元素的总和
就我而言,我需要为来自特定列和两个不同表的匹配项的数量/计数返回一个总数。
例如,我有两个单独的表,每个表都有一个 PhoneNumber 列。在这两个表之间,我想知道该列中有多少匹配。
参考:https://www.guru99.com/joins.html
使用上面相同的表名,它看起来像这样:
SELECT COUNT(DISTINCT m.MESSAGEID) AS COUNT FROM MESSAGE m, MESSAGEPART mp
where mp.MESSAGEID = m.MESSAGEID;