web-dev-qa-db-fra.com

Comment obtenir un groupe dont le nombre est nul?

Je vais essayer de faire un graphique à partir des données de ma base de données SQL Server. J'aurai toutes les rues avec le nombre d'utilisateurs qui vivent dans cette rue, même le nombre est nul.

Pour cela, j'ai essayé cette requête:

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

Et ça me donne cette sortie:

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

Le problème est que la 5ème rue, où aucun utilisateur ne vit, n'apparaît pas sur le résultat. Puis-je faire cela avec SQL Server? Ici vous avez un violon

Mise à jour: Si je le fais right join, J'ai ce résultat:

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

Voir ce violon.

12
H. Pauwelyn

La raison pour laquelle votre requête n'a pas fonctionné comme prévu:

La jointure interne vous donne l'intersection de 2 tables. Dans votre cas, il n'y avait aucune entrée pour 5th street dans votre table d'utilisateurs et c'est pourquoi join n'a produit aucune entrée pour cela.

La jointure externe (droite ou gauche) donnera le résultat de la jointure interne et en plus tous les enregistrements non qualifiés de la table gauche ou droite selon le type (gauche ou droite) de jointure externe.

Dans ce cas, j'ai mis Street à gauche de la jointure et utilisé la jointure externe gauche comme vous vouliez toutes les rues (même le nombre est nul) dans votre jeu de résultats.

Modifiez votre requête de sélection en ceci.

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

Résultat enter image description here

17
SqlWorldWide

C'est une façon possible.

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

Nettoyage du code pour travailler sur une instance sensible à la casse ...

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

Lorsque vous utilisez COUNT avec un nom de colonne, il compte NOT NULL valeurs.

J'utilise un RIGHT JOIN ici pour apaiser 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

Résultats:

street      count
1st street  2
2nd street  5
3rd street  2
4th street  1
5th street  0
7
Erik Darling
  1. Obtenez le nombre par identifiant de rue
  2. rejoindre l'identifiant de la rue avec l'identifiant des rues
  3. Utilisez Coalsesce car la valeur nulle résultera

Voici la courte requête:

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
0
rakesh