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 :

Pouvez-vous m'aider à comprendre cette requête ?


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 96
    Points : 72
    Points
    72
    Par défaut Pouvez-vous m'aider à comprendre cette requête ?
    Bonjour,

    Quelqu'un peut il m'expliquer ce que fait cette requête qui contient 2 jointures qui pour moi sont identiques.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT DISTINCT  table1.champ1 
    FROM table1  INNER JOIN  table2 t2 
      ON table1.t1_ID=t2.t1_ID   
    INNER JOIN  table2 t2Bis 
      ON table1.t1_ID=t2Bis.t1_ID 
    WHERE ( t2.champ1='xxx'  AND t2Bis.champ2='yyy' ) 
    ORDER BY table1.champ1 ASC
    Cette requête ne renvoie pas la même chose que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT DISTINCT  table1.champ1
     FROM table1  INNER JOIN  table2 t2 
      ON table1.t1_ID=t2.t1_ID 
    WHERE ( t2.champ1='xxx'  AND t2.champ2='yyy' ) 
    ORDER BY table1.champ1 ASC
    Merci

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Déjà il n'y a pas de champs en sql, mais des colonnes

    Votre 1ere requête est en effet mauvaise, la 2eme jointure ne sert à rien.

    Maintenant la 2eme requête pourrai surement ce ré-écrire de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT t1.col_1
    FROM table1  t1
    WHERE EXISTS (select 1 from table2 t2 where t1.t1_ID = t2.t2_ID and t2.champ1='xxx'  AND t2.champ2='yyy' ) 
    ORDER BY t1.col_1 ASC

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Merci pour cette réponse.

    Mon problème est que la 1ére requête est dans une appli existante et retourne des résultats. Je n'arrive pas à trouver une requête qui me renvoie la même chose.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Pour comprendre la différence remplace :
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table1.champ1, t2.champ1, t2.champ2, (t2bis.champ1, t2bis.champ2)
    Les filtres WHERE sont différents.

  5. #5
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Bonjour,

    Si tu prend un exemple c'est plus simple à comprendre :

    Table 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ID | libelle
    1  | A
    2  | B
    3  | C
    4  | D
    Table 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ID | Col1 | Col2
    1  | xxx  | aaa
    2  | xxx  | yyy
    3  | bbb  | yyy
    4  | aaa  | bbb
    Avec ta première requête on a :
    t2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ID | Col1 | Col2
    1  | xxx  | aaa
    2  | xxx  | yyy
    t2bis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ID | Col1 | Col2
    2  | xxx  | yyy
    3  | bbb  | yyy
    Avec la jointure avec table1 on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ID | Col1 | Col2 | libelle
    1  | xxx  | aaa  | A
    2  | xxx  | yyy  | B
    3  | bbb  | yyy  | C
    Or dans ta deuxième requête pour ta table 2 tu veux que la col1 = xxx ET la col2 = yyy. Ce qui ne te renvoi que la ligne 2.

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Votre 1ere requête est en effet mauvaise, la 2eme jointure ne sert à rien.
    Pas d'accord, les deux requêtes ne sont pas équivalentes et la deuxième jointure a son utilité.

    C'est un double test d'existence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT t1.champ1
      FROM table1 t1
     WHERE EXISTS (SELECT NULL
                     FROM table2 t2
                    WHERE t1.t1_ID = t2.t1_ID
                      AND t2.champ1 = 'xxx')
       AND EXISTS (SELECT NULL
                     FROM table2 t2
                    WHERE t1.t1_ID = t2.t1_ID
                      AND t2.champ2 = 'yyy')

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 887
    Points : 53 120
    Points
    53 120
    Billets dans le blog
    6
    Par défaut
    Effectivement la différence saute aux yeux...

    Si vous faite un AND en essayant d'avoir sur la même ligne une personne qui s'appelle à la fois DUPONT et MARTIN vous me direz comment vous y arrivez !!!

    Il faut donc bien deux branche de jointures qui parcourent indépendamment l'un de l'autre la seconde table.

    A +

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Effectivement la différence saute aux yeux...

    Si vous faite un AND en essayant d'avoir sur la même ligne une personne qui s'appelle à la fois DUPONT et MARTIN vous me direz comment vous y arrivez !!!

    Il faut donc bien deux branche de jointures qui parcourent indépendamment l'un de l'autre la seconde table.

    A +
    Effectivement j'ai fait une erreur de compréhension sur cette requête, par contre ca sera plutôt une personne qui à pour nom DUPONT ou celle qui ont pour prénom PIOTREK.

    Bref dans ce cas là un seul exists avec un OR ne serai-t-il pas mieux ?

  9. #9
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Non, parce qu'il faut bien que les deux conditions soient réalisées, donc AND.

    Réalisées pas forcément sur la même ligne, donc deux (semi-)jointures.

  10. #10
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    D'ailleurs, en une seule jointure, ça peut s'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT table1.champ1
    FROM table1  INNER JOIN  table2 t2 
      ON table1.t1_ID=t2.t1_ID
    GROUP BY table1.champ1
    HAVING sum(case when t2.champ1 = 'xxx' then 1 else 0 end) > 0
      AND   sum(case when t2.champ2 = 'yyy' then 1 else 0 end) > 0
    (Pas systématiquement plus performant, à voir selon le cas)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Ok merci j'ai compris mon erreur.

    Par contre lola01 votre exemple n'est pas bon, le résultat avec ce jeux de donnée ne retourne qu'une ligne.

    En insérant en plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into table2 values (1, 'aaa', 'yyy');
    On aura ce qui manque pour que l'exemple fonctionne :p

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Merci pour vos réponses.
    Je comprends la requête et dans mon cas elle n'est pas bonne mais maintenant je sais comment elle fonctionne.

    Comme le disait Skautamad mettre ceci dans le select :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table1.champ1, t2.champ1, t2.champ2, (t2bis.champ1, t2bis.champ2)
    aide à bien comprendre.

  13. #13
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par pacmann Voir le message
    D'ailleurs, en une seule jointure, ça peut s'écrire :
    On peut affiner un peu la recherche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      SELECT t1.champ1
        FROM table1 t1
             INNER JOIN table2 t2
               ON t2.t1_ID = t1.t1_ID
       WHERE t2.champ1 = 'xxx'
          OR t2.champ2 = 'yyy'
    GROUP BY t1.champ1
      HAVING sum(case t2.champ1 when 'xxx' then 1 else 0 end) > 0
         AND sum(case t2.champ2 when 'yyy' then 1 else 0 end) > 0;

Discussions similaires

  1. [HTML] Pouvez vous m'aider à comprendre ces balises HTML ?
    Par DionCeli dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 02/07/2008, 11h54
  2. pouvez vous m'aider a optimiser cette requete
    Par taoufikiory dans le forum SQL
    Réponses: 4
    Dernier message: 20/07/2007, 15h32
  3. Je n'arrive pas à faire une pop-up. Pouvez-vous m'aider?
    Par Davidoux94 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/12/2006, 12h24
  4. Pourriez-vous m'aider pour cette simulation de ping ?
    Par andrianiaina dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 07/09/2006, 14h57
  5. Pouvez vous m'aider a resoudres ces 3 exercices
    Par algorithmique dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 09/08/2002, 17h26

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