COUNT toplamda "sıfır" / "0" sonuçları nasıl dahil edilir?


112

Kendimi biraz SQL ile sıkışıp kaldım. Soruyu zekice ifade edebileceğimi sanmıyorum - bu yüzden size göstereyim.

Biri kişi, biri randevu adlı iki masam var. Bir kişinin sahip olduğu randevu sayısını iade etmeye çalışıyorum (sıfır olması da dahil). Randevu içerir person_idve person_idrandevu başına vardır . YaniCOUNT(person_id) mantıklı bir yaklaşımdır.

Sorgu:

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

Doğru bir şekilde dönecektir, bir person_id'in sahip olduğu randevu sayısı. Ancak, 0 randevusu olan bir kişi geri dönmez (tabii ki bu masada olmadıkları için).

İfadeyi kişi tablosundan person_id alacak şekilde değiştirmek bana şöyle bir şey verir:

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;

Ancak bu, yine de sadece randevusu olan bir person_id'i döndürecek ve benim istediğim değil, 0 randevusu olan kişilerle bir dönüş!

Herhangi bir öneri lütfen?


1
Ya sıfır almak istersem | Tek tablodaki sonuç olarak 0. Vm_tool_licenses tablosum var ve sorgu aşağıdaki gibi seç vm_tool_id, count (vm_tool_license_active) vm_tool_license_active, vm_tool_id ile vm_tool_license_active, vm_tool_id sahip vm_tool_license_active = false`
Narendra

Yanıtlar:


101

Bunun için bir dış birleştirme istiyorsunuz (ve "sürüş" masası olarak kişiyi kullanmanız gerekir)

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;

Bunun işe yaramasının nedeni, dış (sol) birleşimin NULLrandevusu olmayan kişiler için geri dönmesidir. Toplama işlevi değerleri count()saymaz NULLve böylece sıfır alırsınız.

Dış birleşimler hakkında daha fazla bilgi edinmek istiyorsanız, işte güzel bir öğretici: http://sqlzoo.net/wiki/Using_Null


ama ya randevunun bazı alanları BOŞ DEĞİLSE (tablo tanımında)?
Lior Yehezkely

@LiorYehezkely: "Bazı sütunların" önemi yok. Count () birleştirme sütununu kullanır. Bu boş değilse, sayılması gereken bir randevu var
a_horse_with_no_name

21

Bunun LEFT JOINyerine kullanmalısınızINNER 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;

1
GROUP BY, tablo sorguya dahil edilmediğinden orijinal soruda bir yazım hatası gibi görünüyor.
Joachim Isaksson

7

Dış birleştirmeyi (sayımla) yaparsanız ve sonra bu sonucu bir alt tablo olarak kullanırsanız, beklendiği gibi 0 elde edebilirsiniz (nvl işlevi sayesinde)

Ör:

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

5

GROUP BY kullanarak sonuçta 0 sayı elde etmek için birleştirme kullanın.

Basitçe 'birleştirme' MS SQL'de İç birleştirme yapar, bu nedenle sol veya sağ birleştirmeye gidin.

Birincil anahtarı içeren tablodan önce QUERY'de bahsediliyorsa, o zaman LEFT birleştirmeyi kullanın, diğer RIGHT birleştirmeyi kullanın.

ÖRNEĞİN:

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

Birincil anahtara sahip tablodan grupla alın ve gerçek girdileri / ayrıntıları olan başka bir tablodan sayın.


2

Orijinal sorgunuzda daha da az değiştirmek için, katılımınızı bir RIGHTbirleştirmeye dönüştürebilirsiniz.

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;

Bu sadece seçilen cevaba dayanır, ancak dış birleşim RIGHTyönde olduğundan, sadece bir kelimenin eklenmesi ve daha az değişiklik yapılması gerekir. - Sadece orada olduğunu ve bazen sorguları daha okunaklı hale getirebileceğini ve daha az yeniden oluşturma gerektirebileceğini unutmayın.


0

LEFT JOIN ile ilgili sorun, randevu yoksa, COUNT ile toplandığında 1 olacak olan boş değer içeren bir satırı yine de döndürecek ve kişinin gerçekte hiç randevusu olmadığı halde bir randevusu olduğu görünecektir. Bunun doğru sonuçları vereceğini düşünüyorum:

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

Ben de aynı çözümü çok basit bir şekilde gönderecektim.
Joel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.