Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 27/01/2011, 14h29   #1
Membre actif
 
Avatar de albedo0
 
Julien C
Inscription : février 2007
Messages : 207
Détails du profil
Informations personnelles :
Nom : Julien C
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : février 2007
Messages : 207
Points : 167
Points : 167
Par défaut Combinaison de JOIN et de count()

Bonjour,

Me revoila encore avec une requête SQL un peu complexe (pour moi du moins sinon je serai pas là...).

La problématique est la suivante, il s'agit de lister des examens en récupérant des informations un peu partout :
1. je récupère les informations du référentiel utilisé pour l'examen : ça marche
Code :
1
2
3
4
SELECT *
FROM exams AS e
LEFT OUTER JOIN referentiels AS r ON e.exam_referent = r.ref_id
ORDER BY exam_title ASC
2. Je récupère ensuite le nombre de groupes utilisant cet examen : ça marche toujours
Code :
1
2
3
4
5
6
SELECT *, count( g.grp_id ) AS nb_grp
FROM exams AS e
LEFT OUTER JOIN referentiels AS r ON e.exam_referent = r.ref_id
LEFT OUTER JOIN groups AS g ON g.grp_exam = e.exam_id
GROUP BY e.exam_id
ORDER BY exam_title ASC
3. Pour finir, je récupère le nombre de questions pour l'examen : ça ne marche plus
Code :
1
2
3
4
5
6
7
SELECT *, count( g.grp_id ) AS nb_grp, count( i.item_id ) AS nb_item
FROM exams AS e
LEFT OUTER JOIN referentiels AS r ON e.exam_referent = r.ref_id
LEFT OUTER JOIN groups AS g ON g.grp_exam = e.exam_id
LEFT OUTER JOIN exams_items AS i ON i.item_exam = e.exam_id
GROUP BY e.exam_id
ORDER BY exam_title ASC
Le nombre de questions retourné (nb_item) est identique au nombre de groupe (nb_grp)...

Quelqu'un aurait-il une idée ?

Merci par avance !!
albedo0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 14h34   #2
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

Il faut utiliser un distinct (ce que vous voulez est bien le nombre de groupes distincts)

Code sql :
1
2
3
4
5
6
7
8
 
SELECT *, count( DISTINCT g.grp_id ) AS nb_grp, count(DISTINCT i.item_id ) AS nb_item
FROM c2i_exams AS e
LEFT OUTER JOIN c2i_referentiels AS r ON e.exam_referent = r.ref_id
LEFT OUTER JOIN c2i_groups AS g ON g.grp_exam = e.exam_id
LEFT OUTER JOIN c2i_exams_items AS i ON i.item_exam = e.exam_id
GROUP BY e.exam_id
ORDER BY exam_title ASC
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 14h39   #3
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Citation:
Envoyé par albedo0 Voir le message
3. Pour finir, je récupère le nombre de questions pour l'examen : ça ne marche plus
Code :
1
2
3
4
5
6
7
SELECT *, count( g.grp_id ) AS nb_grp, count( i.item_id ) AS nb_item
FROM exams AS e
LEFT OUTER JOIN referentiels AS r ON e.exam_referent = r.ref_id
LEFT OUTER JOIN groups AS g ON g.grp_exam = e.exam_id
LEFT OUTER JOIN exams_items AS i ON i.item_exam = e.exam_id
GROUP BY e.exam_id
ORDER BY exam_title ASC
Le nombre de questions retourné (nb_item) est identique au nombre de groupe (nb_grp)...
bonjour,

C'est normal, car là vous comptez le nombre de ligne de votre résultat.

Si vous enlevez le group by il apparaitra une multitude de doublon.

donc je verrai plus un code dans ce style :
Code :
1
2
3
4
5
6
 
SELECT e.exam_id, cnt_grp AS nb_grp, cnt_item AS nb_item
FROM exams AS e
LEFT OUTER JOIN (SELECT grp_exam, count(*) AS cnt_grp FROM groups GROUP BY grp_exam) AS g ON g.grp_exam = e.exam_id
LEFT OUTER JOIN (SELECT item_exam, count(*) AS cnt_item FROM exams_items GROUP BY item_exam) AS i ON i.item_exam = e.exam_id
ORDER BY exam_title ASC
edit : si vos groupe / item ne peuvent être affectés qu'a un seul examen, alors la solution de aieuuu est peut être un peu mieux que celle que je viens de poster. A vérifier avec un plan d'execution ..
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 14h42   #4
Membre actif
 
Avatar de albedo0
 
Julien C
Inscription : février 2007
Messages : 207
Détails du profil
Informations personnelles :
Nom : Julien C
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : février 2007
Messages : 207
Points : 167
Points : 167
Merci pour votre réponse, cela fonctionne très bien (et quelle réactivité !!!).

Par contre, je ne comprend pas le pourquoi du distinct... et j'aime bien comprendre ce que je fais ! Va falloir que je me creuse un peu la cervelle la dessus on dirait...

Merci encore !
albedo0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 14h50   #5
Membre actif
 
Avatar de albedo0
 
Julien C
Inscription : février 2007
Messages : 207
Détails du profil
Informations personnelles :
Nom : Julien C
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : février 2007
Messages : 207
Points : 167
Points : 167
Citation:
Envoyé par punkoff Voir le message
edit : si vos groupe / item ne peuvent être affectés qu'a un seul examen, alors la solution de aieuuu est peut être un peu mieux que celle que je viens de poster. A vérifier avec un plan d'execution ..
C'est effectivement le cas, un groupe est associé à un seul examen et un item n'est associé qu'à un examen !

Je vais effectivement prendre la solution de aieuuu qui reste plus simple !
Merci quand même !!!
albedo0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 15h03   #6
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Votre requête est fausse.
Même si MySQL accepte cette affreuse syntaxe, rien ne vous garanti que vous aurez les mêmes résultats d'une exécution sur l'autre.

On ne fait jamais de select * : prenez deux minutes de plus et listez les colonnes dont vous avez besoin.
On écrit dans le GROUP BY toutes les colonnes qui ne font pas l'objet d'un agrégat.

Utilisez plutôt la syntaxe de punkoff qui est elle parfaitement correcte.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 15h08   #7
Membre actif
 
Avatar de albedo0
 
Julien C
Inscription : février 2007
Messages : 207
Détails du profil
Informations personnelles :
Nom : Julien C
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : février 2007
Messages : 207
Points : 167
Points : 167
J'ai déjà remplacé le * par les noms de colonne, c'est juste une habitude lorsque je fais des test.

Par contre je ne l'aurai pas fait pour le group by... donc je vais corriger ça !

Si cela ne vous prend pas deux heures pour me l'expliquer, en quoi la syntaxe de punkoff est préférable (en respectant les deux points évoqués ci-dessus) ?

Elle me semble nettement moins lisible...
albedo0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h26.


 
 
 
 
Partenaires

Hébergement Web