如何将“零”/“0”结果包含在 COUNT 汇总中?

我只是遇到了一些 SQL 问题。我认为我不能很好地表达这个问题——所以让我展示给你看。

我有两张桌子,一张叫人,一张叫预约。我试图返回一个人的约会次数(包括如果他们没有约会次数)。约会包含 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 具有的约会数。但是,有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;

然而,这仍然只会返回一个已经预约的 person _ id,而不是我想要的返回一个已经预约了0的人!

有什么建议吗?

244583 次浏览

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

您需要一个外部连接(并且需要使用 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;

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

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

如果执行外部连接(使用 count) ,然后将此结果用作子表,则可以得到预期的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

使用 join 在结果中使用 GROUPBY 获取0计数。

简单地‘ join’在 MSSQL 中做内部连接,因此,可以选择左连接或右连接。

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

例如:

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

从具有主键的表中获取 group by,并从具有实际条目/细节的另一个表中获取 count。

若要在原始查询上进行更少的更改,可以将连接转换为 RIGHT连接

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
RIGHT JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;

这只是建立在选定的答案之上,但是由于外部连接是在 RIGHT方向上的,所以只需要添加一个单词,而且更改较少。只要记住它就在那里,有时可以使查询更具可读性,并且需要更少的重建。

左连接的问题在于,如果没有任何约会,它仍然会返回一行带有 null 的内容,当 COUNT 聚合时,这一行将变为1,并且看起来这个人只有一个约会,而实际上他们没有约会。我认为这将给出正确的结果:

SELECT person.person_id,
(SELECT COUNT(*) FROM appointment WHERE person.person_id = appointment.person_id) AS 'Appointments'
FROM person;