Bagaimana cara menyertakan hasil "nol" / "0" dalam COUNT gabungan?

112

Saya baru saja mendapatkan diri saya sedikit terjebak dengan beberapa SQL. Saya rasa saya tidak bisa mengungkapkan pertanyaan itu dengan cemerlang - jadi saya tunjukkan.

Saya memiliki dua meja, satu disebut orang, satu disebut janji temu. Saya mencoba mengembalikan jumlah janji temu yang dimiliki seseorang (termasuk jika mereka nol). Perjanjian berisi person_iddan ada person_idperjanjian per. Begitu COUNT(person_id)pula pendekatan yang masuk akal.

Kueri:

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

Akan kembali dengan benar, jumlah janji temu yang dimiliki person_id. Namun, orang yang memiliki 0 janji temu tidak dikembalikan (jelas karena mereka tidak ada di tabel itu).

Mengubah pernyataan untuk mengambil person_id dari tabel person memberi saya sesuatu seperti:

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;

Namun, ini tetap hanya akan mengembalikan person_id yang memiliki janji dan bukan yang saya inginkan yang merupakan pengembalian dengan orang yang memiliki 0 janji!

Ada saran, tolong?

BrownE
sumber
1
Bagaimana jika saya ingin mendapatkan nol | 0 sebagai hasil di tabel tunggal. Saya memiliki tabel vm_tool_licenses dan kueri seperti di bawah ini pilih vm_tool_id, hitung (vm_tool_license_active) dari grup vm_tool_licenses oleh vm_tool_license_active, vm_tool_id memiliki vm_tool_license_active = false`
Narendra

Jawaban:

101

Anda ingin gabungan luar untuk ini (dan Anda perlu menggunakan orang sebagai tabel "mengemudi")

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;

Alasan mengapa ini berhasil, adalah bahwa gabungan luar (kiri) akan kembali NULLuntuk orang-orang yang tidak memiliki janji. Fungsi agregat count()tidak akan menghitung NULLnilai dan dengan demikian Anda akan mendapatkan nol.

Jika Anda ingin mempelajari lebih lanjut tentang gabungan luar, berikut adalah tutorial yang bagus: http://sqlzoo.net/wiki/Using_Null

seekor kuda tanpa nama
sumber
tetapi bagaimana jika beberapa field dari penunjukan NOT NULL (dalam definisi tabel)?
Lior Yehezkely
@LiorYehezkely: "beberapa kolom" tidak penting. Count () menggunakan kolom gabungan. Jika itu bukan nol, maka ada janji temu yang harus dihitung
a_horse_with_no_name
21

Anda harus menggunakan LEFT JOINbukannyaINNER 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;
Dusun Hakobyan
sumber
1
GROUP BY sepertinya salah ketik pada pertanyaan awal karena tabel tidak disertakan dalam kueri.
Joachim Isaksson
7

jika Anda melakukan gabungan luar (dengan hitungan), dan kemudian menggunakan hasil ini sebagai sub-tabel, Anda bisa mendapatkan 0 seperti yang diharapkan (berkat fungsi 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
Francois Mazet
sumber
5

GUNAKAN bergabung untuk mendapatkan 0 hitungan dalam hasil menggunakan GROUP BY.

cukup 'join' apakah Inner join di MS SQL jadi, Pergi untuk join kiri atau kanan.

Jika tabel yang berisi kunci utama disebutkan pertama di QUERY, maka gunakan Gabung KIRI lain Gabung KANAN.

MISALNYA:

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

Ambil kelompok berdasarkan dari tabel yang memiliki kunci Primer dan hitung dari tabel lain yang memiliki entri / detail aktual.

Rohini CG
sumber
2

Untuk mengubah lebih sedikit pada kueri asli Anda, Anda dapat mengubah gabungan Anda menjadi RIGHTgabungan

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;

Ini hanya dibangun di atas jawaban yang dipilih, tetapi karena gabungan luar RIGHTsearah, hanya satu kata yang perlu ditambahkan dan sedikit perubahan. - Ingatlah bahwa itu ada di sana dan terkadang membuat kueri lebih mudah dibaca dan membutuhkan lebih sedikit pembangunan kembali.

sfj
sumber
0

Masalah dengan LEFT JOIN adalah jika tidak ada janji temu, masih akan mengembalikan satu baris dengan nol, yang bila digabungkan dengan JUMLAH akan menjadi 1, dan akan tampak bahwa orang tersebut memiliki satu janji temu padahal sebenarnya mereka tidak punya janji. Saya pikir ini akan memberikan hasil yang benar:

SELECT person.person_id,
(SELECT COUNT(*) FROM appointment WHERE person.person_id = appointment.person_id) AS 'Appointments'
FROM person;
dannyw
sumber
Saya baru saja akan memposting solusi yang sama ini, sangat sederhana.
Joel