如何在COUNT聚合中包含"零"/"0"结果?

Bro*_*wnE 101 sql postgresql aggregate-functions

我刚刚让自己陷入了一些SQL困境.我不认为我能说出这个问题 - 所以让我告诉你.

我有两张桌子,一张叫人,一张叫约会.我试图返回一个人的约会数量(包括他们有零).约会包含的person_id并有person_id每个预约.所以这COUNT(person_id)是一种明智的做法.

查询:

SELECT person_id, COUNT(person_id) AS "number_of_appointments" 
FROM appointment 
GROUP BY person_id;
Run Code Online (Sandbox Code Playgroud)

将正确返回,person_id具有的约会数量.但是,没有退回约会0的人(显然因为他们不在该表中).

调整语句以从person表中获取person_id给出了类似于:

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;
Run Code Online (Sandbox Code Playgroud)

然而,这仍然只会返回一个有约会的person_id而不是我想要的那个与0个约会的人一起返回的人!

有什么建议吗?

a_h*_*ame 90

你想要一个外部联接(你需要使用person作为"驾驶"表)

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person 
  LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;
Run Code Online (Sandbox Code Playgroud)

这样做的原因是外部(左)联接将返回NULL给那些没有预约的人.聚合函数count()不会计算NULL值,因此您将得到零.

如果你想了解更多关于外连接的信息,这里有一个很好的教程:http://sqlzoo.net/wiki/Using_Null


Ham*_*yan 21

你必须使用LEFT JOIN而不是INNER JOIN

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person 
LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;
Run Code Online (Sandbox Code Playgroud)


小智 7

如果你执行外连接(带计数),然后将此结果用作子表,则可以按预期获得0(感谢nvl函数)

例如:

select P.person_id, nvl(A.nb_apptmts, 0) from 
(SELECT person.person_id
FROM person) P
LEFT JOIN 
(select person_id, count(*) as nb_apptmts
from appointment 
group by person_id) A
ON P.person_id = A.person_id
Run Code Online (Sandbox Code Playgroud)


小智 5

使用GROUP BY通过USE联接获得0计数。

只需使用“ join”就可以在MS SQL中进行内部联接,因此可以进行左右联接。

如果在QUERY中首先提到包含主键的表,则使用LEFT联接,否则使用RIGHT联接。

例如:

select WARDNO,count(WARDCODE) from MAIPADH 
right join  MSWARDH on MSWARDH.WARDNO= MAIPADH.WARDCODE
group by WARDNO
Run Code Online (Sandbox Code Playgroud)

select WARDNO,count(WARDCODE) from MSWARDH
left join  MAIPADH on MSWARDH.WARDNO= MAIPADH.WARDCODE group by WARDNO
Run Code Online (Sandbox Code Playgroud)

从具有主键的表中进行分组,并从具有实际条目/明细的另一个表中进行计数。


dan*_*nyw 5

LEFT JOIN 的问题在于,如果没有约会,它仍然会返回一行带有 null 的行,当按 COUNT 聚合时,该行将变为 1,并且该人看起来有一个约会,但实际上他们没有约会。我认为这会给出正确的结果:

SELECT person.person_id,
(SELECT COUNT(*) FROM appointment WHERE person.person_id = appointment.person_id) AS 'Appointments'
FROM person;
Run Code Online (Sandbox Code Playgroud)