我刚刚让自己陷入了一些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个约会的人一起返回的人!
有什么建议吗?
答案 0 :(得分:80)
你想要一个外部联接(你需要使用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
答案 1 :(得分:18)
您必须使用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;
答案 2 :(得分:5)
如果你进行外连接(带计数),然后将此结果用作子表,你可以按预期得到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
答案 3 :(得分:4)
USE join使用GROUP BY在结果中获得0计数。
简单地说'join'确实在MS SQL中进行内连接,所以Go for left或right join。
如果在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
从具有主键的表中取组,并从具有实际条目/详细信息的另一个表中计数。
答案 4 :(得分:1)
要对原始查询进行的更改更少,您可以将联接变为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
方向,因此仅需添加一个单词,并且所需的更改较少。 -请记住,它在那里,有时可以使查询更具可读性,并且需要较少的重建。
答案 5 :(得分:0)
LEFT JOIN的问题在于,如果没有约会,它仍将返回一个空值的行,当按COUNT进行汇总时,该行将变为1,并且当该人实际拥有一个约会时,该人似乎有一个约会没有。我认为这将给出正确的结果:
SELECT person.person_id,
(SELECT COUNT(*) FROM appointment WHERE person.person_id = appointment.person_id) AS 'Appointments'
FROM person;