一尘不染

计算左联接中的联接行数

sql

我试图用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为行,其中联接的列从MESSAGEPARTNULL?我尝试了以下方法:

逻辑

我试过了

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;

但这又回来了

MESSAGEID   COUNT(*)
-----------------------------------------------
1           2
            1

我在这里做错了什么?


阅读 148

收藏
2021-03-17

共1个答案

一尘不染

这样的事情怎么样:

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()函数将对每一行进行计数,即使它为空。使用SUM()和CASE,您只能计算非空值。

编辑:从顶部注释中获取一个更简单的版本:

SELECT m.MESSAGEID, COUNT(mp.MESSAGEID) FROM MESSAGE m
LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID
GROUP BY m.MESSAGEID;

希望能有所帮助。

2021-03-17