计算左连接中连接行的数量

时间:2013-11-21 11:36:03

标签: sql oracle join count left-join

我正在尝试在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;

我在这里做错了什么?

4 个答案:

答案 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;