[MSSQL] recuperer le nombre de liens d'une table vers une autre ?

Le
Alex
Bonjour a tous,

J'ai une base qui contient entre autres deux tables (A et B) dont un champ
de l'une est une reference (je sais pas si le terme est exact) vers l'autre.
Concretement (et en raccourci avec uniquement les champs qui nous
interessent)

A (object) :
-
object_id
object_name
group_id


B (group) :
--
id
name

En gros, ca permet de regrouper les elements de A (un seul groupe B par
element de A).

Maintenant, j'aimerais faire une requete qui me retourne chaque
enregristrement de B (facile), ainsi que pour chaque B, le nombre de A dont
group_id pointe vers ledit B. Le but c'est de savoir si un groupe n'a plus
aucun appartenant.

J'ai tente pas mal de choses avec des left join, mais meme si j'arrive bien
a joindre les deux tables (ce qui n'est pas mon but), je n'arrive pas a
compter.

Dans ma derniere experience j'ai abandonne le join. J'ai essaye d'executer
une sous-requete :
SELECT B.group_id, B.group_name,
COUNT(SELECT * FROM A where A.group_id = B.id)
FROM B
WHERE 1=1;

La base est sous MSSQL 2000, et je l'attaque depuis du PHP si ca change
quelquechose.

Je pense que mon approche n'est pas la bonne et qu'il y a une syntaxe que je
ne connais pas (je ne suis pas un gros caid en SQL).

Ah oui, j'arrive a le faire avec deux requetes totalement distinctes depuis
mon code PHP, mais je prefererais comprendre comment ca devrait marcher en
SQL propre.

Merci pour votre aide,
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jogo
Le #21852021
Sur fr.comp.applications.sgbd, Alex disait :

Maintenant, j'aimerais faire une requete qui me retourne chaque
enregristrement de B (facile), ainsi que pour chaque B, le nombre de
A dont group_id pointe vers ledit B.



Amha il faut utiliser GROUP BY :

SELECT b.name,count(*)
FROM b LEFT OUTER JOIN a ON b.id=a.group_id
GROUP BY b.name ;

Le but c'est de savoir si un groupe n'a plus aucun appartenant.



Dans ce cas on n'utilise plus WHERE mais HAVING :

SELECT b.name
FROM b LEFT OUTER JOIN a ON b.id=a.group_id
GROUP BY b.name
HAVING count(*)=0 ;

Comme souvent il y a d'autres solutions (il faut tester laquelle est la
plus efficace), par exemple :

SELECT name
FROM b
WHERE id NOT IN (
SELECT DISTINCT group_id FROM a
);

--
À vrai dire, on ne devrait nommer art que le produit de la liberté,
c'est à dire d'un vouloir qui fonde ses actes sur la raison.
-- Kant
Bruno Baguette
Le #21852001
Jogo a écrit :

Comme souvent il y a d'autres solutions (il faut tester laquelle est la
plus efficace), par exemple :

SELECT name
FROM b
WHERE id NOT IN (
SELECT DISTINCT group_id FROM a
);




Je pense qu'en ré-écrivant la requête avec NOT EXISTS, ce serait plus
performant.

Ca donnerait quelque chose du genre

SELECT name
FROM b
WHERE NOT EXISTS
(
SELECT 1
FROM a
WHERE a.group_id = b.id
);

(pas testé)

Bon tuning ! :-)

--
Bruno Baguette -
Alex
Le #21851991
"Jogo" news:
Amha il faut utiliser GROUP BY :

SELECT b.name,count(*)
FROM b LEFT OUTER JOIN a ON b.id=a.group_id
GROUP BY b.name ;



oui mais la, ca me retourne le count de tous les enregistrements de B,
apparemment.

Or je voudrais plutot le count des references a chaque enregistrement de B.

Le but c'est de savoir si un groupe n'a plus aucun appartenant.





J'ai ete trop court. Le but c'est de recuperer tous les groupes, et pour
chaque, le nombre d'appartenants (ce qui permet au traitement de verifier
entre autres si ce nombre est a 0)

Dans ce cas on n'utilise plus WHERE mais HAVING :

SELECT b.name
FROM b LEFT OUTER JOIN a ON b.id=a.group_id
GROUP BY b.name
HAVING count(*)=0 ;

Comme souvent il y a d'autres solutions (il faut tester laquelle est la
plus efficace), par exemple :

SELECT name
FROM b
WHERE id NOT IN (
SELECT DISTINCT group_id FROM a
);



Ces transactions ne me selectionnent pas tout B.

Je retourne tout ca depuis ce matin et j'y arrive pas :)

Merci pour ton aide en tous cas !

--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Alex
Le #21851981
"Alex" news:468e460a$0$22408$
Or je voudrais plutot le count des references a chaque enregistrement de
B.
J'ai ete trop court. Le but c'est de recuperer tous les groupes, et pour
chaque, le nombre d'appartenants (ce qui permet au traitement de verifier
entre autres si ce nombre est a 0)
Ces transactions ne me selectionnent pas tout B.

Je retourne tout ca depuis ce matin et j'y arrive pas :)



Ah j'ai omis une chose. J'y arrive comme ca :
SELECT B.id, B.name, (SELECT COUNT(*) FROM A WHERE A.group_id = B.id) FROM
B;

Mais ca revient a effectuer quand meme une requete separee pour le comptage,
et j'imagine qu'il doit exister un moyen plus propre.

Merci pour vos avis :)
--
Alex
[JDR] Visitez Extremia, un monde gratuit et en francais pour D&D et
autres jeux de role.
www.extremia.org
Jogo
Le #21851971
Sur fr.comp.applications.sgbd, Alex disait :

> SELECT b.name,count(*)
> FROM b LEFT OUTER JOIN a ON b.id=a.group_id
> GROUP BY b.name ;

oui mais la, ca me retourne le count de tous les enregistrements de
B, apparemment.



Non, mais c'est vrai qu'il y avait une erreur. Voilà ce qui marche :

SELECT b.name,count(a.object_id)
FROM b LEFT OUTER JOIN a ON b.id=a.group_id
GROUP BY b.name ;

--
On n'éprouve jamais l'amour pour la première fois, on se le rappelle
toujours, prévient Danilo Martuccelli, pour qui le véritable organe de
l'amour n'est ni le coeur, ni le sexe, mais l'imagination.
- Serge Chaumier - La déliaison amoureuse -
Publicité
Poster une réponse
Anonyme