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 20/12/2011, 10h38   #1
Nouveau Membre du Club
 
Inscription : octobre 2002
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2002
Messages : 86
Points : 36
Points : 36
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 :
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 :
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
david42 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 10h50   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 654
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 654
Points : 2 656
Points : 2 656
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 :
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
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 11h02   #3
Nouveau Membre du Club
 
Inscription : octobre 2002
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2002
Messages : 86
Points : 36
Points : 36
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.
david42 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 11h10   #4
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 928
Points : 1 928
Pour comprendre la différence remplace :
par
Code :
table1.champ1, t2.champ1, t2.champ2, (t2bis.champ1, t2bis.champ2)
Les filtres WHERE sont différents.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 11h15   #5
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 983
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 983
Points : 1 693
Points : 1 693
Bonjour,

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

Table 1
Code :
1
2
3
4
5
ID | libelle
1  | A
2  | B
3  | C
4  | D
Table 2
Code :
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 :
1
2
3
ID | Col1 | Col2
1  | xxx  | aaa
2  | xxx  | yyy
t2bis
Code :
1
2
3
ID | Col1 | Col2
2  | xxx  | yyy
3  | bbb  | yyy
Avec la jointure avec table1 on a :
Code :
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.
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 11h29   #6
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
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 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 :
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')
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 12h54   #7
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 959
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 959
Points : 17 791
Points : 17 791
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 +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 13h13   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 654
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 654
Points : 2 656
Points : 2 656
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 ?
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 13h29   #9
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
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.
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 13h34   #10
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
D'ailleurs, en une seule jointure, ça peut s'écrire :

Code :
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)
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 13h40   #11
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 654
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 654
Points : 2 656
Points : 2 656
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 :
1
2
 
INSERT INTO table2 VALUES (1, 'aaa', 'yyy');
On aura ce qui manque pour que l'exemple fonctionne :p
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 14h12   #12
Nouveau Membre du Club
 
Inscription : octobre 2002
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2002
Messages : 86
Points : 36
Points : 36
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 :
table1.champ1, t2.champ1, t2.champ2, (t2bis.champ1, t2bis.champ2)
aide à bien comprendre.
david42 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2011, 14h37   #13
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
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 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 :
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;
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h28.


 
 
 
 
Partenaires

Hébergement Web