Как включить "ноль" / "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 ответов:
вы хотите внешнее соединение для этого (и вам нужно использовать 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
joinSELECT 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
направление, только одно слово должно быть добавлено и меньше изменений. - Просто помните, что он есть и иногда может сделать запросы более читабельными и требовать меньше перестройки.