IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Sélection et tri sur deux tables


Sujet :

Langage SQL

  1. #1
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Points : 470
    Points
    470
    Par défaut Sélection et tri sur deux tables
    Bonjour,

    C'est un problème assez récurrent chez moi, mais je suis encore en train de lutter pour sélectionner les éléments d'une table en fonction d'éléments situés dans une autre table.

    Imaginons des réunions, qu'on appel Session et constitué de plusieurs créneaux horaires sur des jours différents...

    donc
    Session ( id_session, session.nom_session )
    Creneaux (id_creneaux, #session_creneaux, debut_creneaux)

    Je veux récupérer et (trier organiser) toutes les sessions débutant entre :debut et :fin.

    J'ai écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    select 
       session.id_session, 
       c2.debut 
    from 
       creneaux as c1
          left join (select creneaux.id_creneaux, min(debut_creneaux) as debut from creneaux group by creneaux.id_creneaux ) as c2 on c1.id_creneaux = c2.id_creneaux, 
       session 
    where 
       c2.debut between :debut and :fin 
       and session.id_session = c1.session_creneaux
    group by 
       session.id_session 
    order by 
       c2.debut
    Le résultat étant la liste de toutes les sessions ayant un creneaux entre :debut et :fin, comme si j'avais fait une relation simple entre session et creneaux.

    Qu'est-ce donc que je fait mal ?

    En vous remerciant !

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Qu'est-ce donc que je fait mal ?
    Pour commencer, tu mélanges la jointure moderne (JOIN) et la vieille syntaxe obsolète depuis 20 ans (FROM des tables WHERE condition) !

    Ensuite, Le GROUP BY n'a de sens que si tu utilises une fonction de groupage dans le SELECT ou dans un HAVING.

    Enfin, tu te compliques la vie !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT s.id_session, c.debut
    FROM session s
    INNER JOIN creneaux c ON c.session = s.id_session
    WHERE c.debut BETWEEN :debut AND :fin
    ORDER BY c.debut
    Au passage, tu devrais nommer tes tables au singulier.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

  3. #3
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Points : 470
    Points
    470
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Enfin, tu te compliques la vie !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT s.id_session, c.debut
    FROM session s
    INNER JOIN creneaux c ON c.session = s.id_session
    WHERE c.debut BETWEEN :debut AND :fin
    ORDER BY c.debut
    Heuuuu... mais ça fait pas du tout du tout ce que je cherche à faire ça... En fait, c'est même exactement ce que je cherche à ne pas faire... Ca, ça sort juste la liste des créneaux compris dans l'intervalle spécifié avec le numéro de session qui va avec...

    Non, moi, je veux la liste des sessions unique (je m'excuse, j'ai oublié le distinct dans mon select, c'est parce que je devais le mettre qu'il y a un group by), débutant dans l'intervalle spécifié (donc min(debut_creneaux) associé qui répond au between), et le tout trié par date de début de la session...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT 
       distinct(session.id_session), 
       c2.debut 
    FROM 
       creneaux AS c1
          LEFT JOIN (SELECT creneaux.id_creneaux, min(debut_creneaux) AS debut FROM creneaux GROUP BY creneaux.id_creneaux ) AS c2 ON c1.id_creneaux = c2.id_creneaux, 
       session 
    WHERE 
       c2.debut BETWEEN :debut AND :fin 
       AND session.id_session = c1.session_creneaux
    GROUP BY 
       session.id_session 
    ORDER BY 
       c2.debut
    Merci malgré tout d'avoir répondu

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Si vous ne voulez que la liste des sessions utilisez un EXIST.

    Mais apparemment vous voulez plus !

    L'idée de la sous-requête est bonne, ceci convient ?

    En supposant que #session_creneaux référence id_session...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT s.id_session, c.debut
    FROM Session s
    inner join (
     select session_creneaux, min(debut_creneaux) AS debut 
     FROM creneaux
     where debut_creneaux between :debut and :fin
     group by session_creneaux) as c on s.id_session = c.session_crenaux
    Sinon d'un point de vu générale ca sert à rien de mettre des distinct / group by de partout, soit l'un soit l'autre mais pas les deux en même temps.

    Et ici je doute qu'il y en est besoin dans la requête principale

  5. #5
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Points : 470
    Points
    470
    Par défaut
    Je pense que ça ne marchera pas... Avec cette méthode, je vais récupérer le 1er créneau de la session dans l'intervalle spécifié, mais pas le début de la session... Si je fixe un interval entre le 01/06/2013 et 01/07/2012, une session débutant en janvier mais ayant au moins un créneaux par moi va sortir, et sera marquée comme débutant a son 1er créneau de juin, alors qu'elle débute en janvier et ne devrait donc pas apparaître !


    --- EDIT ---

    La solution était malgré tout très inspirée puisqu'en sortant le between du select imbriqué, cela fonctionne parfaitement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT s.id_session, c.debut
    FROM Session s
    INNER JOIN (
     SELECT session_creneaux, min(debut_creneaux) AS debut 
     FROM creneaux
     GROUP BY session_creneaux) AS c ON s.id_session = c.session_creneaux where c.debut BETWEEN :debut AND :fin
    Un grand merci !

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Et bien au lieu de distiller les infos poste après poste mettez clairement votre besoin car on ne va pas jouer au devinette tout le we

    Proposez un jeu de donnée en entrée + jeu de donnée en sortie avec les différents cas spéciaux qu'il faut gérer.

  7. #7
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Points : 470
    Points
    470
    Par défaut
    non mais le problème était bien posé depuis le début... Il fallait juste la liste des sessions débutant dans un intervalle donné...

    Session ( id_session, session.nom_session )
    Creneaux (id_creneaux, #session_creneaux, debut_creneaux)

    Je veux récupérer et trier toutes les sessions débutant entre :debut et :fin.
    Mais tout va bien, j'ai eu le temps pendant que vous répondiez d'adapter votre dernière proposition, et ça marche !

    Encore merci et Résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Tri sur deux tables
    Par Jefty dans le forum Langage SQL
    Réponses: 4
    Dernier message: 29/03/2013, 11h57
  2. [1.x] Stratégie de tri sur deux tables
    Par Fused dans le forum Symfony
    Réponses: 4
    Dernier message: 10/02/2011, 09h32
  3. [AC-2007] Requête sélection sur deux tables liées
    Par rogerfon dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 10/04/2010, 14h30
  4. Requete sur deux tables avec tri
    Par ebaoo dans le forum MySQL
    Réponses: 2
    Dernier message: 25/02/2010, 18h41
  5. Tri sur deux tables
    Par GriffinK dans le forum Langage SQL
    Réponses: 3
    Dernier message: 25/01/2010, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo