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 :

Conceptualisation jointure


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 13
    Points : 12
    Points
    12
    Par défaut Conceptualisation jointure
    Bonjour,

    J'aurai besoin d'un petit coup de pouce pour construire une requete avec jointure.

    Imaginons 2 tables :
    MAGASIN {ID_MAG} et CLIENT{ID_CLI, ID_MAG}

    Je voudrais une requête qui me retourne tous les magasins ayant pour client "client12" + les magasins n'ayant pas de clients.

    En gros il faudrait faire un truc comme ca mais en plus propre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT MAGASIN .ID_MAG
    FROM MAGASIN , CLIENT 
    WHERE 
    (MAGASIN.ID_MAG = CLIENT.ID_MAG 
    AND CLIENT.ID_CLI = "client12") 
    OR (MAGASIN.ID_MAG NOT IN (SELECT ID_MAG FROM CLIENT))
    J'ai lu relu rerelu le tuto http://sqlpro.developpez.com/cours/sqlaz/jointures/ mais tout ca reste encore brouillon dans ma tete.

    Je pensais à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN
    LEFT OUTER JOIN CLIENT
    ON 
    (MAGASIN.ID_MAG = CLIENT.ID_MAG 
    AND CLIENT.ID_CLIENT= "client12")

    Merci de m'indiquer si ma solution est correcte et sinon merci de me filer une tite solution avec l'explication qui va bien (si possible )

    Cdlt

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 920
    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 920
    Points : 51 712
    Points
    51 712
    Billets dans le blog
    6
    Par défaut
    Non, c'est faut, voici la bonne réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN AS M
    LEFT OUTER JOIN CLIENT AS C
    ON M.ID_MAG = C.ID_MAG 
    WHERE C.ID_CLIENT= 'client12' OR C.ID_CLIENT IS NULL
    Attention, les chaines de caractères dans SQL se délimitent par l'apostrophe et non par des guillemets.

    A +

  3. #3
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Je pensais à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT MAGASIN.ID_MAG 
         FROM MAGASIN
         LEFT OUTER JOIN CLIENT
               ON 
                 (MAGASIN.ID_MAG = CLIENT.ID_MAG 
                 AND CLIENT.ID_CLIENT= "client12")
    Tu as mélangé condition de jointure et condition de restriction.
    Ta requête devrait plutôt être écrite de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN
    LEFT OUTER JOIN CLIENT ON MAGASIN.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT = 'client12'
    Au passage :
    1) Les parenthèses ne sont utiles qu'en cas d'ambiguïté.
    Par exemple, WHERE (A ET B) OU C est différent de WHERE A ET (B OU C)
    Dans ta requête, il n'y a pas besoin de parenthèses.

    2) Les valeurs alphanumériques s'écrivent entre apostrophes, pas entre guillemets.

    Les tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE TABLE Magasin (
     ID_MAG int(10) unsigned NOT NULL AUTO_INCREMENT,
     NOM_MAG varchar(30) COLLATE utf8_unicode_ci NOT NULL,
     PRIMARY KEY (ID_MAG),
     UNIQUE KEY NOM_MAG (NOM_MAG)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    CREATE TABLE CLIENT (
     ID_CLIENT int(10) unsigned NOT NULL AUTO_INCREMENT,
     ID_MAG int(10) unsigned NOT NULL,
     NOM_CLIENT varchar(30) COLLATE utf8_unicode_ci NOT NULL,
     PRIMARY KEY (ID_CLIENT),
     UNIQUE KEY NOM_CLIENT (NOM_CLIENT),
     KEY ID_MAG (ID_MAG),
     CONSTRAINT CLIENT_ibfk_1 FOREIGN KEY (ID_MAG) REFERENCES Magasin (ID_MAG) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    Quelques données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    INSERT INTO test.Magasin (NOM_MAG) 
    VALUES (Mag_1), (Mag_2), (Mag_3), (Mag_4);
     
    INSERT INTO test.CLIENT (ID_MAG, NOM_CLIENT) 
    VALUES (1, 'Dupont'),
      (1, 'Durand')
      (2, 'Dugenou'), 
      (3, 'Duschnock');
    Le magasin 1 a deux clients, les magasins 2 et 3 ont 1 client et le magasin 4 n'en a pas.

    Résultat de ta requête pour le client n° 1 : Les 4 magasins sont retournés.
    Changeons un peu la requête pour voir ce qui s'est passé, en affichant le client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Magasin.ID_MAG, CLIENT.ID_CLIENT
    FROM Magasin
    LEFT OUTER JOIN CLIENT ON Magasin.ID_MAG = CLIENT.ID_MAG 
      AND CLIENT.ID_CLIENT = 1
    Résultat :
    ID_MAG ID_CLIENT
    1 1
    2 NULL
    3 NULL
    4 NULL
    => Le SGBD a pris tous les magasins et a cherché ceux qui ont le client 1.
    Il n'y en a qu'un seul mais comme c'est une jointure externe partant du magasin, il affiche tous les magasins et NULL dans la colonne du client.


    Résultat de ma requête pour le client n° 1 : Seul le magasin 1 (celui du client 1) est retourné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Magasin.ID_MAG, CLIENT.ID_CLIENT
    FROM Magasin
    LEFT OUTER JOIN CLIENT ON Magasin.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT = 1
    => Le SGBD a pris tous les magasins et a fait la jointure avec les clients. Ensuite, il n'a gardé que le client 1

    Revenons à ton besoin :
    Je voudrais une requête qui me retourne tous les magasins ayant pour client "client12" + les magasins n'ayant pas de clients.
    Ta requête retourne tous les magasins :
    - le magasin qui a le client 12 ;
    - les magasins qui ont d'autres clients que le 12 ;
    - les magasins qui n'ont pas de clients.
    En fait, dans ton besoin, il y a deux demandes différentes :
    1) Les magasins ayant le client 12 ;
    2) Les magasins n'ayant pas de client.

    Requête pour le besoin 1) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN
    INNER JOIN CLIENT ON MAGASIN.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT = 'client12'
    Requête pour le besoin 2) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN
    LEFT OUTER JOIN CLIENT ON MAGASIN.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT IS NULL
    Vérifions avec mes données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Magasin.ID_MAG, CLIENT.ID_CLIENT
    FROM Magasin
    LEFT OUTER JOIN CLIENT ON Magasin.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT IS NULL
    Résultat :
    ID_MAG ID_CLIENT
    4 NULL
    => On n'affiche bien que le magasin n'ayant pas de client.

    Si tu veux les deux dans la même requête, il faut faire mettre les deux conditions de restriction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT MAGASIN.ID_MAG 
    FROM MAGASIN
    LEFT OUTER JOIN CLIENT ON MAGASIN.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT IS NULL
      OR CLIENT.ID_CLIENT = 'client12'
    Vérifions avec mes données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Magasin.ID_MAG, CLIENT.ID_CLIENT
    FROM Magasin
    LEFT OUTER JOIN CLIENT ON Magasin.ID_MAG = CLIENT.ID_MAG 
    WHERE CLIENT.ID_CLIENT IS NULL
      OR CLIENT.ID_CLIENT = 1
    Résultat :
    ID_MAG ID_CLIENT
    1 1
    4 NULL

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Merci pour les explications ca m'a bien éclairé

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Tant que j'y suis j'aimerai savoir comment on doit procéder si jamais on veut appliquer plusieurs demandes ?

    Typiquement :
    1) Les magasins ayant le client 12
    2) Les magasins n'ayant pas de client
    3) Les magasins ayant le fournisseur 28
    4) Les magasins n'ayant pas de fournisseur
    5) Les magasins ayant une adresse sur Paris
    6) Les magasins n'ayant pas d'adresse

    Sachant que les données fournisseur, adresse, client et magasin sont dans des tables différentes.

    Pour réaliser ce genre de calcul on effectue les jointures les unes après les autres ? on utilise UNION ?

  6. #6
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    C'est bizarre de vouloir mélanger ces demandes différentes !
    Déjà de vouloir les magasins du client12 et les magasins sans client dans la même requête, c'est sémantiquement bizarre ! Dans quel but ?

    1) Les magasins ayant le client 12
    2) Les magasins n'ayant pas de client
    3) Les magasins ayant le fournisseur 28
    4) Les magasins n'ayant pas de fournisseur
    5) Les magasins ayant une adresse sur Paris
    6) Les magasins n'ayant pas d'adresse
    Si tu veux les magasins parisiens ayant le client 12 qui ont travaillé avec le fournisseur 28, ça peut se faire en une requête et c'est sémantiquement cohérent puisque le résultat peut s'exprimer logiquement en français.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT m.ID_MAG
    FROM MAGASIN AS m
    INNER JOIN CLIENT AS c ON c.ID_MAG = m.ID_MAG 
    INNER JOIN MAG_FOUR AS mf ON mf.ID_MAG = m.ID_MAG
    INNER JOIN VILLE AS v ON v.ID_VILLE = m.ID_VILLE
    WHERE c.ID_CLIENT = 12
      AND mf.ID_FOURN = 28
      AND v.NOM_VILLE = 'Paris'
    Ajouter les besoins 2, 4 et 6 devient déjà moins compréhensible.

    Commence par exprimer ton besoin par une phrase en français.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    C'était juste une question par simple curiosité mais en tout cas je vois mieux la logique derrière tout ca. Il est important de bien cerner et formuler le besoin, ca fait la moitié du boulot.

    Merci pour ton aide, je décapiterai un poney en ton honneur

  8. #8
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par unclebounty Voir le message
    je décapiterai un poney en ton honneur
    Oh ben non eh ! Pauv' poney !

    En plus je m'appelle Philippe => philos hippos => qui aime les chevaux !
    Et ma fille est cavalière !

    Écrase un moustique, ça suffira !

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

Discussions similaires

  1. Jointure qui ne renvoie pas tous les enregistrements
    Par rayonx dans le forum Langage SQL
    Réponses: 12
    Dernier message: 19/07/2024, 10h33
  2. pb jointure texture
    Par dweis dans le forum DirectX
    Réponses: 2
    Dernier message: 24/06/2003, 14h33
  3. Jointures en SQL
    Par Guizz dans le forum Langage SQL
    Réponses: 10
    Dernier message: 04/06/2003, 13h21
  4. Réponses: 14
    Dernier message: 17/03/2003, 19h31
  5. Jointures INNER et jointures classiques ???
    Par UbiK dans le forum Langage SQL
    Réponses: 3
    Dernier message: 05/09/2002, 11h29

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