[MSSQL] Encore plus fort : recuperer le nombre de lien de DEUX tables vers une troisieme.
6 réponses
Alex
Hello,
Suite a ma question de la semaine derniere, je me retrouve avec le meme
genre situation avec DEUX tables.
Rappel de la situation :
A :
----
Aid
Aname
Agroup_id_in_C (pointe vers C.Cid)
Agroup_id_in_B (pointe vers B.Bid)
B :
--
Bid
Bname
Bgroup_id_in_C (pointe vers C.Cid)
C :
--
Cid
Cname
Je veux faire un select sur C qui me retourne aussi une colonne contenant le
nombre de A et de B qui pointent vers C.
J'arrive a compter le nombre de A qui pointent vers C ainsi :
SELECT Cid, Cname, count(Aid) FROM C LEFT JOIN A on C.Cid = A.Agroup_id_in_C
GROUP BY Cid, Cname
J'arrive a compter le nombre de B qui pointent vers C ainsi :
SELECT Cid, Cname, count(Bid) FROM C LEFT JOIN B on C.Cid = B.Bgroup_id_in_C
GROUP BY Cid, Cname
Mais ceci ne marche pas :
SELECT Cid, Cname, count(Bid), count(Aid)
FROM C
LEFT JOIN B ON C.Cid = B.Bgroup_id_in_C
LEFT JOIN C ON C.Cid = A.Agroup_id_in_C
GROUP BY Cid, Cname
Ca n'echoue pas, ca me retourne bien deux colonnes de count, mais elles
contiennent la meme chose, qui est en gros le count(Aid).
Comment faire ? suis-je oblige de passer par des sous-requetes ?
Merci beaucoup !
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Jogo
Sur fr.comp.applications.sgbd, Alex disait :
Comment faire ? suis-je oblige de passer par des sous-requetes ?
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP BY. Il en faut forcement deux, par exemple (pas testé) :
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0) FROM C LEFT OUTER JOIN ( SELECT Agroup_id_in_C AS cid, count(*) AS nb FROM A GROUP BY Agroup_id_in_C) X ON c.cid = x.cid LEFT OUTER JOIN ( SELECT Bgroup_id_in_C AS cid, count(*) AS nb FROM B GROUP BY Bgroup_id_in_C) Y ON c.cid = y.cid
-- Once ... in the wilds of Afghanistan, I lost my corkscrew, and we were forced to live on nothing but food and water for days. -- W. C. Fields, "My Little Chickadee"
Sur fr.comp.applications.sgbd, Alex disait :
Comment faire ? suis-je oblige de passer par des sous-requetes ?
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP BY. Il en faut forcement deux, par exemple (pas testé) :
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0)
FROM C
LEFT OUTER JOIN (
SELECT Agroup_id_in_C AS cid, count(*) AS nb
FROM A GROUP BY Agroup_id_in_C) X
ON c.cid = x.cid
LEFT OUTER JOIN (
SELECT Bgroup_id_in_C AS cid, count(*) AS nb
FROM B GROUP BY Bgroup_id_in_C) Y
ON c.cid = y.cid
--
Once ... in the wilds of Afghanistan, I lost my corkscrew, and we were
forced to live on nothing but food and water for days.
-- W. C. Fields, "My Little Chickadee"
Comment faire ? suis-je oblige de passer par des sous-requetes ?
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP BY. Il en faut forcement deux, par exemple (pas testé) :
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0) FROM C LEFT OUTER JOIN ( SELECT Agroup_id_in_C AS cid, count(*) AS nb FROM A GROUP BY Agroup_id_in_C) X ON c.cid = x.cid LEFT OUTER JOIN ( SELECT Bgroup_id_in_C AS cid, count(*) AS nb FROM B GROUP BY Bgroup_id_in_C) Y ON c.cid = y.cid
-- Once ... in the wilds of Afghanistan, I lost my corkscrew, and we were forced to live on nothing but food and water for days. -- W. C. Fields, "My Little Chickadee"
Alex
"Jogo" wrote in message news:
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP BY. Il en faut forcement deux, par exemple (pas testé) :
Je soupconnais effectivement qu'un seul group by faisait que le regroupement etait applique aux deux tables, ce qui est incorrect.
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0) FROM C LEFT OUTER JOIN ( SELECT Agroup_id_in_C AS cid, count(*) AS nb FROM A GROUP BY Agroup_id_in_C) X ON c.cid = x.cid LEFT OUTER JOIN ( SELECT Bgroup_id_in_C AS cid, count(*) AS nb FROM B GROUP BY Bgroup_id_in_C) Y ON c.cid = y.cid
Effectivement ca marche comme ca. Je ne connaissais pas coalesce.
Par contre en pratique, apres avoir essaye pour ma culture generale, je suis tente de rester sur une formulation avec un seul left join et une seule sous requete du type suivant : SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from B where B.group_id_in_C = C.cid) FROM C LEFT OUTER JOIN A ON A.group_id_in_C = C.cid GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une sous-requete, non ?
Merci de m'avoir indique coalesce, en tous cas. -- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org
"Jogo" <jogo@matabio.net> wrote in message
news:20070713110523.55d89104.jogo@matabio.net...
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP
BY. Il en faut forcement deux, par exemple (pas testé) :
Je soupconnais effectivement qu'un seul group by faisait que le regroupement
etait applique aux deux tables, ce qui est incorrect.
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0)
FROM C
LEFT OUTER JOIN (
SELECT Agroup_id_in_C AS cid, count(*) AS nb
FROM A GROUP BY Agroup_id_in_C) X
ON c.cid = x.cid
LEFT OUTER JOIN (
SELECT Bgroup_id_in_C AS cid, count(*) AS nb
FROM B GROUP BY Bgroup_id_in_C) Y
ON c.cid = y.cid
Effectivement ca marche comme ca. Je ne connaissais pas coalesce.
Par contre en pratique, apres avoir essaye pour ma culture generale, je suis
tente de rester sur une formulation avec un seul left join et une seule sous
requete du type suivant :
SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from B where
B.group_id_in_C = C.cid)
FROM C
LEFT OUTER JOIN A ON A.group_id_in_C = C.cid
GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une
sous-requete, non ?
Merci de m'avoir indique coalesce, en tous cas.
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Je pense que oui. En tout cas, on ne peut pas n'utiliser qu'un seul GROUP BY. Il en faut forcement deux, par exemple (pas testé) :
Je soupconnais effectivement qu'un seul group by faisait que le regroupement etait applique aux deux tables, ce qui est incorrect.
SELECT c.cid, c.cname, coalesce(x.nb,0), coalesce(y.nb,0) FROM C LEFT OUTER JOIN ( SELECT Agroup_id_in_C AS cid, count(*) AS nb FROM A GROUP BY Agroup_id_in_C) X ON c.cid = x.cid LEFT OUTER JOIN ( SELECT Bgroup_id_in_C AS cid, count(*) AS nb FROM B GROUP BY Bgroup_id_in_C) Y ON c.cid = y.cid
Effectivement ca marche comme ca. Je ne connaissais pas coalesce.
Par contre en pratique, apres avoir essaye pour ma culture generale, je suis tente de rester sur une formulation avec un seul left join et une seule sous requete du type suivant : SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from B where B.group_id_in_C = C.cid) FROM C LEFT OUTER JOIN A ON A.group_id_in_C = C.cid GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une sous-requete, non ?
Merci de m'avoir indique coalesce, en tous cas. -- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org
Jogo
Sur fr.comp.applications.sgbd, Alex disait :
SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from B where B.group_id_in_C = C.cid) FROM C LEFT OUTER JOIN A ON A.group_id_in_C = C.cid GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une sous-requete, non ?
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de mettre une sous-requête avant le FROM. Non seulement parce que ce n'est pas sa place, mais il n'est pas impossible que le planificateur fasse une sous-requête par ligne de résultat. Bref, ama il n'y a pas *qu'une* sous-requête dans cette requête.
-- Il y a plus d'un jupon entre la robe et la culotte. -- Nounou Ogg
Sur fr.comp.applications.sgbd, Alex disait :
SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from
B where B.group_id_in_C = C.cid)
FROM C
LEFT OUTER JOIN A ON A.group_id_in_C = C.cid
GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une
sous-requete, non ?
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de
mettre une sous-requête avant le FROM. Non seulement parce que ce
n'est pas sa place, mais il n'est pas impossible que le planificateur
fasse une sous-requête par ligne de résultat. Bref, ama il n'y a
pas *qu'une* sous-requête dans cette requête.
--
Il y a plus d'un jupon entre la robe et la culotte.
-- Nounou Ogg
SELECT c.cid, c.cname, count(A.group_id_in_C), (select count(*) from B where B.group_id_in_C = C.cid) FROM C LEFT OUTER JOIN A ON A.group_id_in_C = C.cid GROUP BY c.cid, c.cname
Je pense que cette formulation est plus legere car il n'u a qu'une sous-requete, non ?
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de mettre une sous-requête avant le FROM. Non seulement parce que ce n'est pas sa place, mais il n'est pas impossible que le planificateur fasse une sous-requête par ligne de résultat. Bref, ama il n'y a pas *qu'une* sous-requête dans cette requête.
-- Il y a plus d'un jupon entre la robe et la culotte. -- Nounou Ogg
Alex
"Jogo" wrote in message news:
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de mettre une sous-requête avant le FROM. Non seulement parce que ce n'est pas sa place, mais il n'est pas impossible que le planificateur fasse une sous-requête par ligne de résultat. Bref, ama il n'y a pas *qu'une* sous-requête dans cette requête.
OK, je comprends ce que tu veux dire. C'est bien vu.
Je vais regarder si je vois une difference quelconque entre les deux methodes a l'usage. Mais comme de toutes facons la charge serveur est vraiment minime, j'ai peur qu'on ne voie rien en fait.
Merci, -- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org
"Jogo" <jogo@matabio.net> wrote in message
news:20070716141328.a69a758d.jogo@matabio.net...
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de
mettre une sous-requête avant le FROM. Non seulement parce que ce
n'est pas sa place, mais il n'est pas impossible que le planificateur
fasse une sous-requête par ligne de résultat. Bref, ama il n'y a
pas *qu'une* sous-requête dans cette requête.
OK, je comprends ce que tu veux dire. C'est bien vu.
Je vais regarder si je vois une difference quelconque entre les deux
methodes a l'usage. Mais comme de toutes facons la charge serveur est
vraiment minime, j'ai peur qu'on ne voie rien en fait.
Merci,
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Rien n'est moins sûr. En règle générale, c'est une mauvaise idée de mettre une sous-requête avant le FROM. Non seulement parce que ce n'est pas sa place, mais il n'est pas impossible que le planificateur fasse une sous-requête par ligne de résultat. Bref, ama il n'y a pas *qu'une* sous-requête dans cette requête.
OK, je comprends ce que tu veux dire. C'est bien vu.
Je vais regarder si je vois une difference quelconque entre les deux methodes a l'usage. Mais comme de toutes facons la charge serveur est vraiment minime, j'ai peur qu'on ne voie rien en fait.
Merci, -- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org
Jogo
Sur fr.comp.applications.sgbd, Alex disait :
Je vais regarder si je vois une difference quelconque entre les deux methodes a l'usage. Mais comme de toutes facons la charge serveur est vraiment minime, j'ai peur qu'on ne voie rien en fait.
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça : http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
-- Voter [parallélogramme] était permis, mais seulement le dimanche, si je ne m'abuse. *- Zelda Touque sur fr.rec.jeux.nomic -*
Sur fr.comp.applications.sgbd, Alex disait :
Je vais regarder si je vois une difference quelconque entre les deux
methodes a l'usage. Mais comme de toutes facons la charge serveur est
vraiment minime, j'ai peur qu'on ne voie rien en fait.
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va
faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la
cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça :
http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
--
Voter [parallélogramme] était permis,
mais seulement le dimanche, si je ne m'abuse.
*- Zelda Touque sur fr.rec.jeux.nomic -*
Je vais regarder si je vois une difference quelconque entre les deux methodes a l'usage. Mais comme de toutes facons la charge serveur est vraiment minime, j'ai peur qu'on ne voie rien en fait.
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça : http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
-- Voter [parallélogramme] était permis, mais seulement le dimanche, si je ne m'abuse. *- Zelda Touque sur fr.rec.jeux.nomic -*
Alex
"Jogo" wrote in message news:
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça : http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
Interessant ! Je vais garder ca sous le coude !
-- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org
"Jogo" <jogo@matabio.net> wrote in message
news:20070716175906.0427ee42.jogo@matabio.net...
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va
faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la
cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça :
http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
Interessant ! Je vais garder ca sous le coude !
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Il faut que tu vois ce que le planificateur (ou l'ordonnanceur) va faire de tes requêtes pour pouvoir comparer. Avec pgSQL, il y a la cmmande EXPLAIN. Pour MSSQL, j'ai trouvé ça : http://rudi.developpez.com/sqlserver/tutoriel/optimisation/#LI-B
Interessant ! Je vais garder ca sous le coude !
-- Alex [JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et autres jeux de role. www.extremia.org