Bagaimana cara mendapatkan grup yang penghitungannya nol?


12

Saya akan mencoba membuat grafik dari data dari database SQL server saya. Saya akan memiliki semua jalan dengan jumlah pengguna yang tinggal di jalan ini bahkan hitungannya nol.

Untuk ini, saya sudah mencoba kueri ini:

Create table Streets(
  ID int IDENTITY  primary key,
  Name varchar(100)
);

create table users(
  ID int IDENTITY  primary key,
  Username varchar(100),
  StreetID int references Streets(id)
);

insert into streets values ('1st street'), ('2nd street'), ('3rd street'), 
                           ('4th street'), ('5th street');
insert into users values ('Pol', 1), ('Doortje', 1), ('Marc', 2), ('Bieke', 2), 
                         ('Paulien', 2), ('Fernand', 2), ('Pascal', 2), ('Boma', 3), 
                         ('Goedele', 3), ('Xavier', 4);

select s.name as street, count(s.name) as count 
from users u inner join streets s on u.streetid = s.id
group by s.name

Dan itu memberi saya hasil ini:

|   | street     | count |
| - | ---------- | ----- |
| 1 | 1st street | 2     |
| 2 | 2nd street | 5     |
| 3 | 3rd street | 2     |
| 4 | 4th street | 1     |

Masalahnya adalah bahwa jalan ke-5, tempat tidak ada pengguna yang hidup, tidak muncul pada hasilnya. Bisakah saya melakukan ini dengan SQL server? Di sini Anda punya biola

Pembaruan: Jika saya melakukannya right join, saya mendapatkan hasil ini:

|   | street     | count |
| - | ---------- | ----- |
| 1 | 1st street | 2     |
| 2 | 2nd street | 5     |
| 3 | 3rd street | 2     |
| 4 | 4th street | 1     |
| 5 | 5th street | 1     | 

Lihat biola ini.


4
Karena tidak ada yang menjelaskan mengapa permintaan Anda tidak mengembalikan hasil yang diharapkan: Saat fungsi agregat mengabaikan NULL, Anda harus menghitung kolom dari tabel bagian dalam (Anda dihitung dari tabel luar) yang dikenal didefinisikan sebagai BUKAN NULL (untuk dapat membedakan antara NULL dalam data dan NULL yang dibuat oleh Outer Join). Cara termudah adalah dengan menghitung kolom bergabung:COUNT(u.streetid)
dnoeth

Karena right joindan right outer joinmerupakan hal yang sama. Saya memang menambahkan penjelasan dalam jawaban saya seperti yang disarankan oleh @ jpmc26.
SqlWorldWide

Jawaban:


17

Alasan kueri Anda tidak berfungsi seperti yang dimaksudkan:

Gabungan dalam memberi Anda persimpangan 2 tabel. Dalam kasus Anda, tidak ada entri untuk 5th streetdi tabel pengguna Anda dan itulah sebabnya bergabung tidak menghasilkan entri apa pun untuk itu.

Gabung luar (kanan atau kiri) akan memberikan hasil gabung dalam dan di samping itu semua catatan yang tidak memenuhi syarat dari tabel kiri atau kanan tergantung pada jenis (kiri atau kanan) gabung luar.

Dalam hal ini, saya meletakkan Street di sebelah kiri gabungan dan menggunakan gabungan luar kiri seperti yang Anda inginkan semua jalan (bahkan hitungan nol) di kumpulan hasil Anda.

Ubah kueri pemilihan Anda menjadi ini.

SELECT S.Name AS Street,
       Count(U.Username) AS COUNT
FROM Streets S
LEFT OUTER JOIN Users U ON U.Streetid = S.Id
GROUP BY S.Name

Hasil masukkan deskripsi gambar di sini


1
Bagi saya, mengubah dari hitungan (*) ke menghitung (customer.id) - mirip dengan yang ditunjukkan di atas - membuat perbedaan kritis. Terima kasih :)
Zeek

9

Ini adalah salah satu cara yang mungkin.

select s.name as streets,
       (select count(*)
        from   users
        where  StreetID = s.id) cnt
from   streets s;

7

Membersihkan kode agar berfungsi pada instance case sensitif ...

CREATE TABLE Streets
(
    ID INT IDENTITY PRIMARY KEY,
    Name VARCHAR(100)
);

CREATE TABLE users
(
    ID INT IDENTITY PRIMARY KEY,
    Username VARCHAR(100),
    StreetID INT
        REFERENCES Streets ( ID )
);

INSERT INTO Streets
VALUES ( '1st street' ),
    ( '2nd street' ),
    ( '3rd street' ),
    ( '4th street' ),
    ( '5th street' );
INSERT INTO users
VALUES ( 'Pol', 1 ),
    ( 'Doortje', 1 ),
    ( 'Marc', 2 ),
    ( 'Bieke', 2 ),
    ( 'Paulien', 2 ),
    ( 'Fernand', 2 ),
    ( 'Pascal', 2 ),
    ( 'Boma', 3 ),
    ( 'Goedele', 3 ),
    ( 'Xavier', 4 );

Saat Anda menggunakan COUNTdengan nama kolom, itu menghitung NOT NULLnilai.

Saya menggunakan di RIGHT JOINsini untuk menenangkan Joe Obbish.

SELECT   s.Name AS street, COUNT(u.Username) AS count
FROM     users AS u
RIGHT JOIN Streets AS s
ON u.StreetID = s.ID
GROUP BY s.Name

Hasil:

street      count
1st street  2
2nd street  5
3rd street  2
4th street  1
5th street  0

0
  1. Dapatkan penghitungan dengan ID jalan
  2. bergabung dengan id jalan dengan id dari jalanan
  3. Gunakan Coalsesce sebagai nilai nol akan dihasilkan

Ini pertanyaan singkatnya:

select Name, coalesce( u.ct,0)ct FROM streets s left join (
select StreetID,count(*)ct from users group by StreetID)u on s.ID=u.StreetID

Itu dengan kiri bergabung
rakesh
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.