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/04/2011, 22h04   #1
Invité de passage
 
Inscription : avril 2011
Messages : 2
Détails du profil
Informations forums :
Inscription : avril 2011
Messages : 2
Points : 2
Points : 2
Par défaut Difficulté avec une requête SQL

Bonjour,

Tout d'abord, mes excuses pour le titre : je n'ai pas trouvé plus éloquent.

J'ai en effet besoin d'aide pour construire une requête.

La situation est la suivante. Je possède deux tables avec deux attributs en "commun". J'utilise des guillemets car j'aimerais faire une jointure avec une condition : si attribut de la table 1 n'est pas dans la table 2, alors considéré sa valeur à 0.

Ayant du mal aussi avec l'explication textuelle, je vous ai mis un exemple en fichier joint. Comme vous pouvez le voir, si dans la table 1, nous avons le couple (IdPays, IdEquipe) dans la table 2, on fait une jointure normale.

Par contre, si dans la table 1, seul l'attribut IdPays se trouve dans la table 2, on considère l'attribut IdEquipe avec une valeur égale à 0 pour la jointure.

Si je n'ai pas été assez clair, n'hésitez pas à me questionner.

En vous remerciant grandement d'avance pour la lecture de mon post et potentiellement votre aide.
Images attachées
Type de fichier : png probleme.png (15,5 Ko, 9 affichages)
tokuhigh est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/04/2011, 01h56   #2
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
S'il n'y a bien qu'un IdEquipe à 0 par IdPays alors tu peux essayer :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
SELECT e.*,
       coalesce(ep.NomEquipe,(SELECT NomEquipe 
                                FROM equipe ep2 
                               WHERE ep2.IdPays = e.IdPays 
                                 AND ep2.IdEquipe = 0
                             )
                ) AS NomEquipe
  FROM employe e
  LEFT JOIN equipe ep 
    ON e.IdPays = ep.IdPays 
   AND e.IdEquipe = ep.IdEquipe
 ORDER BY IdEmp
En gros une jointure externe (LEFT JOIN) pour récupérer toutes les lignes de employe, puis quand elle n'a pas de correspondance (donc NULL) utiliser coalesce et une requête corrélée.

J'ai un peu réfléchi à comment éviter la requête corrélée, mais je ne vois rien de super fancy, je poste un jeu de test pour ceux qui auraient de meilleurs idées (mais une requête corrélée n'est pas mauvaise en soit surtout si la base est correctement indexée) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
WITH employe AS (
  SELECT 1 AS IdEmp, 36000 AS IdPays  , 3 AS IdEquipe, 250 AS Salaire FROM dual union ALL
  SELECT 2         , 36001            , 1            , 400            FROM dual union ALL
  SELECT 3         , 36000            , 5            , 600            FROM dual union ALL
  SELECT 4         , 36002            , 1            , 200            FROM dual union ALL
  SELECT 5         , 36000            , 6            , 100            FROM dual union ALL
  SELECT 6         , 36000            , 18           , 300            FROM dual
),
equipe AS (
  SELECT 36000 AS IdPays, 3 AS IdEquipe, 'EquipeA' AS NomEquipe FROM dual union ALL
  SELECT 36000          , 0            , 'EquipeABis'           FROM dual union ALL
  SELECT 36001          , 1            , 'EquipeB'              FROM dual union ALL
  SELECT 36002          , 1            , 'EquipeC'              FROM dual
)
SELECT e.*,
       coalesce(ep.NomEquipe,(SELECT NomEquipe 
                                FROM equipe ep2 
                               WHERE ep2.IdPays = e.IdPays 
                                 AND ep2.IdEquipe = 0
                             )
                ) AS NomEquipe
  FROM employe e
  LEFT JOIN equipe ep 
    ON e.IdPays = ep.IdPays 
   AND e.IdEquipe = ep.IdEquipe
 ORDER BY IdEmp
 
     IDEMP     IDPAYS   IDEQUIPE    SALAIRE NOMEQUIPE
---------- ---------- ---------- ---------- ----------
         1      36000          3        250 EquipeA
         2      36001          1        400 EquipeB
         3      36000          5        600 EquipeABis
         4      36002          1        200 EquipeC
         5      36000          6        100 EquipeABis
         6      36000         18        300 EquipeABis
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/04/2011, 12h31   #3
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 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Avec deux jointures !
Code sql :
1
2
3
4
5
6
7
8
9
10
SELECT emp.IdEmp, emp.IdPays, emp.IdEquipe, emp.Salaire,
       coalesce(ep1.NomEquipe, ep2.NomEquipe) AS NomEquipe
  FROM employe emp
       LEFT OUTER JOIN equipe ep1 
         ON ep1.IdPays   = emp.IdPays 
        AND ep1.IdEquipe = emp.IdEquipe
       LEFT OUTER JOIN equipe ep2
         ON ep2.IdPays   = emp.IdPays
        AND ep2.IdEquipe = 0
 ORDER BY emp.IdEmp ASC;
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/04/2011, 20h50   #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 929
Points : 1 929
Citation:
Envoyé par Waldar Voir le message
Avec deux jointures !
(au moins j'avais écrit le jeu de test...)
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/04/2011, 23h42   #5
Invité de passage
 
Inscription : avril 2011
Messages : 2
Détails du profil
Informations forums :
Inscription : avril 2011
Messages : 2
Points : 2
Points : 2
Merci à tous les deux.

J'avais bidouillé quelque chose semblable à la proposition de skuatamad. Mais le coup de la double jointure me convient parfaitement .
tokuhigh 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 03h03.


 
 
 
 
Partenaires

Hébergement Web