Как включить "ноль" / "0" результатов в совокупности?


Я просто немного застрял с некоторыми 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_id из таблицы person, дает мне что-то вроде:

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 назначений!

любые предложения, пожалуйста?

5 78

5 ответов:

вы хотите внешнее соединение для этого (и вам нужно использовать 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

вы должны использовать 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, как ожидалось (благодаря функции nvl)

Ex:

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, чтобы получить 0 count в результате использования GROUP BY.

просто "join" делает внутреннее соединение в MS SQL, поэтому перейдите на левое или правое соединение.

Если таблица, содержащая первичный ключ, упоминается сначала в запросе, то используйте LEFT join else RIGHT join.

например:

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 из таблицы, которая имеет первичный ключ и подсчет из другой таблицы, которая имеет фактические записи/детали.

чтобы изменить еще меньше в исходном запросе, вы можете превратить свое соединение в RIGHT join

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 направление, только одно слово должно быть добавлено и меньше изменений. - Просто помните, что он есть и иногда может сделать запросы более читабельными и требовать меньше перестройки.