2013-02-09 329 views
67

我刚刚得到了一些SQL的困扰。我不认为我可以出色地提出这个问题 - 所以让我给你看看。如何在COUNT聚合中包含“零”/“0”结果?

我有两张桌子,一个叫人,一个叫约会。我正在尝试返回一个人的约会次数(包括零次数)。约会包含person_id,每个约会有person_id。所以COUNT(person_id)是一个明智的做法。

查询:

SELECT person_id, COUNT(person_id) AS "number_of_appointments" 
FROM appointment 
GROUP BY person_id; 

将正确返回,约会为person_id拥有的数量。但是,一个没有任命的人不会被退回(显然,因为他们不在该表中)。

调整,以从人表取为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; 

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

有什么建议吗?

回答

58

你想为这个外连接(你需要使用人的“驾驶”表)

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; 

之所以这样,正在工作,对于那些没有预约的人来说,外(左)连接将返回NULL。聚合函数count()不会计入NULL值,因此您将得到一个零。

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

17

您必须使用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; 
+0

由于表未包含在查询中,GROUP BY看起来像原来问题中的拼写错误。 – 2013-02-10 00:07:41

+0

@JoachimIsaksson我的错误。当然 :) – 2013-02-10 00:08:48

4

如果做外连接(与计数),然后用这个结果作为子表,你可以得到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 
1

使用连接来获得使用GROUP BY结果0计数。

只需'连接'就可以在MS SQL内部连接,所以左右连接。

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

EG:

select WARDNO,count(WARDCODE) from MAIPADH 
right join MSWARDH on MSWARDH.WARDNO= MAIPADH.WARDCODE 
group by WARDNO 

select WARDNO,count(WARDCODE) from MSWARDH 
left join MAIPADH on MSWARDH.WARDNO= MAIPADH.WARDCODE group by WARDNO 

从具有主键和从具有实际条目/细节的另一个表计数的表中分组。