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 |
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
C'est une façon possible.
select s.name as streets,
(select count(*)
from users
where StreetID = s.id) cnt
from streets s;
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
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