Question
J'ai trois tables :page, pièce jointe, page-pièce jointe
J'ai des données comme ceci :
page
ID NAME
1 first page
2 second page
3 third page
4 fourth page
attachment
ID NAME
1 foo.word
2 test.xsl
3 mm.ppt
page-attachment
ID PAGE-ID ATTACHMENT-ID
1 2 1
2 2 2
3 3 3
Je souhaite obtenir le nombre de pièces jointes par page aussi quand ce nombre est 0.J'ai essayé avec :
select page.name, count(page-attachment.id) as attachmentsnumber
from page
inner join page-attachment on page.id=page-id
group by page.id
J'obtiens cette sortie :
NAME ATTACHMENTSNUMBER
second page 2
third page 1
J'aimerais obtenir ce résultat :
NAME ATTACHMENTSNUMBER
first page 0
second page 2
third page 1
fourth page 0
Comment obtenir la partie 0 ?
La solution
Remplacez votre "jointure interne" par une "jointure externe gauche", ce qui signifie "récupérez-moi toutes les lignes à gauche de la jointure, même s'il n'y a pas de ligne correspondante à droite".
select page.name, count(page-attachment.id) as attachmentsnumber
from page
left outer join page-attachment on page.id=page-id
group by page.name
Autres conseils
Voici une autre solution utilisant la sous-requête.
SELECT
p.name,
(
SELECT COUNT(*) FROM [page-attachment] pa
WHERE pa.[PAGE-ID] = p.id
) as attachmentsnumber
FROM page p
En fonction de la base de données, pour plus de rapidité, vous pouvez utiliser la commande UNION.
Le SQL est plus long, mais, selon la base de données, il accélère les choses en séparant « compter les choses qui sont là » et « compter les choses qui ne sont pas là ».
(
select page.name, count(page-attachment.id) as attachmentsnumber
from page
inner join page-attachment on page.id=page-id
group by page.id
)
UNION
(
select page.name, 0 as attachmentsnumber
from page
where page.id not in (
select page-id from page-attachment)
)
La base de données pour laquelle j'ai besoin de cette solution contient 20 pages dans plus d'un million de pièces jointes.L'UNION l'a fait fonctionner en 13 secondes plutôt que si longtemps que je me suis ennuyé et j'ai essayé une autre méthode (quelque part au-dessus de 60 secondes avant de tuer les méthodes de jointure externe et de sous-requête).
Vous souhaitez une jointure gauche, au lieu d'une jointure interne, car cela permet aux enregistrements de ne pas exister.
La jointure GAUCHE est votre ami.Pour en savoir plus sur les différents types de jointure, reportez-vous à http://en.wikipedia.org/wiki/Join_(SQL)
Utilisez ceci:
SELECT p.name,(
SELECT COUNT(*) FROM [page-attachment] pa WHERE pa.[PAGE-ID] = p.id) as attachmentsnumber
FROM page p