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

iq3niunx  于 2022-12-26  发布在  Oracle
关注(0)|答案(4)|浏览(240)

我正在尝试用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表执行左连接,但是对于那些从MESSAGEPART连接的列是NULL的行,我如何返回0的计数呢?
逻辑
我试过了

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

我到底做错了什么?

ru9i0ody

ru9i0ody1#

不如这样:

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;
xienkqul

xienkqul2#

我认为,您 * 首先 * 希望在加入之前在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
bq8i3lrv

bq8i3lrv3#

不要忘记使用DISTINCT,以防您将LEFT JOIN多个表:

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

4si2a6ki4#

    • 基于匹配列,返回一个数字作为两个表之间匹配元素的总数**

在我的例子中,我需要一个返回的总数来表示来自特定列和两个不同表的匹配项的数目/计数。
例如,我有两个单独的表,每个表都有一个PhoneNumber列。在这两个表之间,我想知道该列中有多少匹配。
参考:https://www.guru99.com/joins.html
使用上面相同的表名,它将如下所示:

SELECT COUNT(DISTINCT m.MESSAGEID) AS COUNT FROM MESSAGE m, MESSAGEPART mp
where mp.MESSAGEID = m.MESSAGEID;

相关问题