Come ottenere un gruppo in cui il conteggio è zero?


12

Proverò a creare un grafico dai dati dal mio database del server SQL. Avrò tutte le strade con il conteggio degli utenti che vivono in questa strada anche il conteggio è zero.

Per questo ho provato questa query:

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

E mi dà questo risultato:

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

Il problema è che la quinta strada, dove non vive nessun utente, non appare sul risultato. Potrei farlo con SQL Server? Qui hai un violino

Aggiornamento: se lo faccio right join, ho questo risultato:

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

Vedi questo violino.


4
Poiché nessuno ha spiegato perché la tua query non restituisce il risultato atteso: poiché la funzione di aggregazione ignora i NULL, devi contare una colonna dalla tabella interna (hai contato dalla tabella esterna) che è noto per essere definito come NOT NULL (per poter distinguere tra NULL all'interno dei dati e NULL creato da Outer Join). Il modo più semplice è contare la colonna di join:COUNT(u.streetid)
17:00

Perché right joine right outer joinsono le stesse cose. Ho aggiunto una spiegazione nella mia risposta come suggerito da @ jpmc26.
SqlWorldWide,

Risposte:


17

Il motivo per cui la tua query non ha funzionato come previsto:

Il join interno fornisce l'intersezione di 2 tabelle. Nel tuo caso, non vi era alcuna voce 5th streetnella tabella degli utenti ed è per questo che join non ha prodotto alcuna voce per questo.

Il join esterno (destro o sinistro) fornirà il risultato del join interno e inoltre tutti i record non qualificanti dalla tabella sinistra o destra a seconda del tipo (sinistro o destro) del join esterno.

In questo caso, ho messo Street a sinistra del join e ho usato il join esterno sinistro come desiderato per tutte le strade (anche il conteggio è zero) nel set di risultati.

Cambia la tua query di selezione in questo.

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

Risultato inserisci qui la descrizione dell'immagine


1
Per me, passare da count (*) a count (customer.id) - simile a quello mostrato sopra - ha fatto la differenza fondamentale. Grazie :)
Zeek,

9

Questo è un modo possibile.

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

7

Pulizia del codice per lavorare su un'istanza sensibile al maiuscolo / minuscolo ...

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 );

Quando si utilizza COUNTcon un nome di colonna, conta i NOT NULLvalori.

Sto usando un RIGHT JOINqui per placare 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

risultati:

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

0
  1. Ottieni il conteggio per ID strada
  2. Unisciti all'ID strada con ID dalle strade
  3. Usa Coalsesce come risultato null

Ecco la breve domanda:

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

Cioè con join sinistro
rakesh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.