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 14/02/2011, 15h24   #1
Invité de passage
 
Inscription : octobre 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 12
Points : 1
Points : 1
Par défaut REQUETE multi jointure

Bonjour

J’ai un souci de lenteur avec une requête avec plusieurs jointures
en effet, avec la première jointure ca va, mais dès que j’en mets une autre, c’est lent.

J’aimerai savoir pour chaque ELEVE :
en ANGLAIS : leur 1er cours , leur dernier cours
en MATHS : leur 1er cours , leur dernier cours
en PHYSIQUE : leur 1er cours , leur dernier cours

Je fais :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT E.eleve_id
 
, MIN(Ca. DATE_COURS) AS ‘1er Anglais’
, MAX(Ca. DATE_COURS) AS ‘derner Anglais’
, MIN(Cm. DATE_COURS) AS ‘1er Maths’
, MAX(Cm. DATE_COURS) AS ‘derner Maths’
, MIN(Cp. DATE_COURS) AS ‘1er Physique
, MAX(Cp. DATE_COURS) AS ‘derner Physique
FROM eleves E
–(ex 1 = anglais, 2 = maths…)
LEFT JOIN cours Ca ON Ca.eleve_id = E.eleve_id AND Ca. GENRE_COURS   = 1 
LEFT JOIN cours Cm ON Cm.eleve_id = E.eleve_id AND Cm. GENRE_COURS   = 2
LEFT JOIN cours Cp ON Cp.eleve_id = E.eleve_id AND Cp. GENRE_COURS   = 3
GROUP BY E.eleve_id

Merci
olive_olive est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 15h36   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 240
Points : 18 240
Envoyer un message via MSN à CinePhil
Si GENRE_COURS est une clé étrangère faisant référence à une autre table qui contiendrait par exemple une colonne libelle_cours, tu peux faire une seule jointure sur la table cours :
Code :
1
2
3
4
5
6
7
8
SELECT e.eleve_id, gc.libelle_cours, 
    MIN(ca.DATE_COURS) AS premier,
    MAX(ca.DATE_COURS) AS dernier
FROM eleves E
LEFT OUTER JOIN cours ca ON ca.eleve_id = E.eleve_id
    LEFT OUTER JOIN genre_cours gc ON gc.genre_cours_id = ca.genre_cours -- A adapter ici aux vraies tables
WHERE ca.GENRE_COURS BETWEEN 1 AND 3 -- Si la liste des id n'est pas continue, utiliser IN
GROUP BY e.eleve_id, gc.libelle_cours
Et bien sûr il faut que toutes les colonnes figurant dans les conditions de jointures soient indexées pour avoir de bonnes performances.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 16h30   #3
Invité de passage
 
Inscription : octobre 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 12
Points : 1
Points : 1
Par défaut REQUETE multi jointure

super mais j'ai oublié une précision

je ne souhaite m'occuper que des élèves présents en 2010

ex : MARC
1er ANGLAIS = '01/01/2009'
dernier ANGLAIS = '01/10/2009'
1er MATHS = '01/05/2009'
Dernier MATHS = '01/06/2010'

ex : PAUL
1er ANGLAIS = '01/01/2009'
dernier ANGLAIS = '01/10/2009'
1er MATHS = '01/05/2009'
Dernier MATHS = '01/06/2009'

ici je dois avoir MARC mais pas PAUL (car il n'est pas venu en 2010)

merci en tout ca pour tes réponse
olive_olive est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 16h58   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 240
Points : 18 240
Envoyer un message via MSN à CinePhil
Ben tu ajoutes une condition de restriction sur les dates dans le WHERE !
Code :
1
2
3
4
5
6
7
8
9
SELECT e.eleve_id, gc.libelle_cours, 
    MIN(ca.DATE_COURS) AS premier,
    MAX(ca.DATE_COURS) AS dernier
FROM eleves E
LEFT OUTER JOIN cours ca ON ca.eleve_id = E.eleve_id
    LEFT OUTER JOIN genre_cours gc ON gc.genre_cours_id = ca.genre_cours -- A adapter ici aux vraies tables
WHERE ca.GENRE_COURS BETWEEN 1 AND 3 -- Si la liste des id n'est pas continue, utiliser IN
    AND ca.DATE_COURS BETWEEN '2010-01-01' AND '2010-12-31'
GROUP BY e.eleve_id, gc.libelle_cours
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 17h07   #5
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
bonjour

Citation:
je ne souhaite m'occuper que des élèves présents en 2010

dans ce cas une petite clause HAVING, genre (en suivant le modele de cinephil)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT e.eleve_id, gc.libelle_cours, 
    MIN(ca.DATE_COURS) AS premier,
    MAX(ca.DATE_COURS) AS dernier
FROM eleves E
LEFT OUTER JOIN cours ca ON ca.eleve_id = E.eleve_id
    LEFT OUTER JOIN genre_cours gc ON gc.genre_cours_id = ca.genre_cours -- A adapter ici aux vraies tables
WHERE ca.GENRE_COURS BETWEEN 1 AND 3 -- Si la liste des id n'est pas continue, utiliser IN
    AND ca.DATE_COURS BETWEEN '2010-01-01' AND '2010-12-31'
GROUP BY e.eleve_id, gc.libelle_cours
 
 
HAVING EXTRACT(YEAR OF MIN(ca.DATE_COURS) = 2010) OR 
           EXTRACT(YEAR OF MAX(ca.DATE_COURS) = 2010)  -- pour prevoir les deux cas (le max en 2011)
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 17h26   #6
Invité de passage
 
Inscription : octobre 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 12
Points : 1
Points : 1
hé non car dans ce cas, je n'aurais pas le 1er cours mais uniquement le 1er cours DE l'année.

or je cherche son 1er cours

ex : MARC
1er ANGLAIS = '01/01/2009'
dernier ANGLAIS = '01/10/2009'
1er MATHS = '01/05/2009'
Dernier MATHS = '01/06/2010'

merci
olive_olive est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 17h44   #7
Invité de passage
 
Inscription : octobre 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 12
Points : 1
Points : 1
Je reformule :

Pour les ELEVES présents en 2010

Quel est leur 1er et Dernier cours d’ANGLAIS
Quel est leur 1er et Dernier cours de MATHS
Quel est leur 1er et Dernier cours de PHYSIQUE

Peu importe l’année de ces cours.

ex : MARC
1er ANGLAIS = '01/01/2009'
dernier ANGLAIS = '01/10/2009'
1er MATHS = '01/05/2009'
Dernier MATHS = '01/06/2010'

ex : PAUL
1er ANGLAIS = '01/01/2009'
dernier ANGLAIS = '01/10/2009'
1er MATHS = '01/05/2009'
Dernier MATHS = '01/06/2009'

ici je dois avoir MARC mais pas PAUL (car il n'est pas venu en 2010)

pour MARC, il est bien venu en 2010 et son 1er cours ANGLAIS était en 2009

merci
olive_olive est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 23h00   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 240
Points : 18 240
Envoyer un message via MSN à CinePhil
OK alors il faut décomposer le problème...

Si je comprends bien, c'est la date du cours qui détermine si un élève est présent ou non une année, du moment qu'il a participé à au moins un cours au cours de l'année ?

1) Quels sont les élèves présents en 2010 ?
Code :
1
2
3
SELECT DISTINCT eleve_id
FROM cours
WHERE DATE_COURS BETWEEN '2010-01-01' AND '2010-12-31'
2) Pour ces élèves, quel est le premier et le dernier cours auquel ils ont participé dans chaque matière choisie ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT e.eleve_id, gc.libelle_cours, 
    MIN(ca.DATE_COURS) AS premier,
    MAX(ca.DATE_COURS) AS dernier
FROM eleves E
INNER JOIN
(
  SELECT DISTINCT eleve_id
  FROM cours
  WHERE DATE_COURS BETWEEN '2010-01-01' AND '2010-12-31'
) tmp ON tmp.eleve_id = E.eleve_id
LEFT OUTER JOIN cours ca ON ca.eleve_id = E.eleve_id
    LEFT OUTER JOIN genre_cours gc ON gc.genre_cours_id = ca.genre_cours -- A adapter ici aux vraies tables
WHERE ca.GENRE_COURS BETWEEN 1 AND 3 -- Si la liste des id n'est pas continue, utiliser IN
GROUP BY e.eleve_id, gc.libelle_cours
ORDER BY e.eleve_id, gc.libelle_cours
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 23h43   #9
Invité de passage
 
Inscription : octobre 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 12
Points : 1
Points : 1
Milles merci

bonne soirée
olive_olive 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 10h37.


 
 
 
 
Partenaires

Hébergement Web