Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

5 réponses
Avatar
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

5 réponses

Avatar
Jogo
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
Avatar
Bruno Baguette
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 -
Avatar
Alex
"Jogo" wrote in message
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
Avatar
Alex
"Alex" wrote in message
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
Avatar
Jogo
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 -