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 :

LEFT JOIN sur tables identiques ?


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Par défaut LEFT JOIN sur tables identiques ?
    [Table NUMERO]
    Code [Table NUMERO] : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    NOM    | NUMERO_FIXE | NUMERO_MOBILE
    ---------------------------------
    DUPONT | 0112345678  | 0112345678
    DUPONT | 0612345678  | 0612345678

    Est-ce que vous auriez une 'belle' solution à mon problème ?

    Moi qui vient tout juste d'apprendre la manipulation du JOIN, et uniquement pour l'expliquer à quelqu'un d'autre, j'aurais tendance à me contenter d'un :
    Lé JOIN cé d'la maird'hanb' Harr

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    591
    Détails du profil
    Informations personnelles :
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2009
    Messages : 591
    Par défaut
    Bonjour,

    Moi qui vient tout juste d'apprendre la manipulation du JOIN, et uniquement pour l'expliquer à quelqu'un d'autre, j'aurais tendance à me contenter d'un :
    Citation:
    Lé JOIN cé d'la maird'hanb' Harr
    C'est peut être aller un peu vite dans le jugement.

    Ton SQL doit bien supporter l'instruction CASE alors, il convient de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT C.NOM,
       CASE WHEN T.TYPE_NUMERO = 'FIXE' THEN T.NUMERO END AS NumeroFixe, 
       CASE WHEN T.TYPE_NUMERO = 'MOBILE' THEN T.NUMERO END AS NumeroMobile, 
    FROM CLIENT C,
       LEFT JOIN TELEPHONE T ON C.ID_CLIENT = T.ID_CLIENT
    Il est peut avantageux de remplacer LEFT JOIN par un INNER JOIN. Tout cela dépend de ton application.

    Maintenant, il faut se poser la question si c'est le travail de la base de données de présenter les résultats en colonne. Pour ma part, je pense que c'est à l'applicatif d'effectuer la mise en forme.

    Notre ami CinePhil te dirait, la cosmétique ce n'est pas le travail de ta base de données

    @+

  3. #3
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 456
    Par défaut
    Bonjour,
    J'ajouterai que tu compares une requêtes sans JOIN, mais avec des critères de sélection sur le type de numéro, et une requête avec JOIN, mais sans les critères en question. Donc pas étonnant que le résultat soit légèrement différent...

    Tatayo.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 454
    Par défaut
    seabs, n'oubliez pas l'agrégat sur les numéros, actuellement votre requête renvoie deux lignes.

  5. #5
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Sans les JOIN, c'est simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT C.NOM, N1.NUMERO, N2.NUMERO
    FROM CLIENT C, NUMERO N1, NUMERO N2
    WHERE C.ID_CLIENT = N1.ID_CLIENT
    AND C.ID_CLIENT = N2.ID_CLIENT
    AND N1.TYPE_NUMERO = 'FIXE'
    AND N2.TYPE_NUMERO = 'MOBILE'
    L'équivalent avec un LEFT JOIN :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT C.NOM, N1.NUMERO, N2.NUMERO
    FROM (CLIENT C
     LEFT JOIN NUMERO N1
     ON C.ID_CLIENT = N1.ID_CLIENT)
     LEFT JOIN NUMERO N2
     ON C.ID_CLIENT = N2.ID_CLIENT
    Perdu, l'équivalent avec les joins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT C.NOM, N1.NUMERO, N2.NUMERO
    FROM CLIENT C
     LEFT JOIN NUMERO N1
     ON C.ID_CLIENT = N1.ID_CLIENT AND N1.TYPE_NUMERO = 'FIXE'
     LEFT JOIN NUMERO N2
     ON C.ID_CLIENT = N2.ID_CLIENT AND N2.TYPE_NUMERO = 'MOBILE'

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Par défaut
    Merci à seabs et Waldar pour vos réponses instructives.

    Citation Envoyé par seabs
    Ton SQL doit bien supporter l'instruction CASE
    Il semble supporter le "CASE" ... mais pas le "WHEN" !!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Mot clé non reconnu WHEN.
    J'vais fouiller des conseils sur des forums SQL / VB, car ça me parait bizzare qu'il ne reconnaisse qu'une partie du CASE/WHEN THEN.
    Une autre idée sinon ?

    Citation Envoyé par Waldar
    seabs, n'oubliez pas l'agrégat sur les numéros, actuellement votre requête renvoie deux lignes.
    Euh ... d'ailleurs, j'vois pas quoi agréger pour retirer les lignes en trop.

    Citation Envoyé par seabs
    Maintenant, il faut se poser la question si c'est le travail de la base de données de présenter les résultats en colonne. Pour ma part, je pense que c'est à l'applicatif d'effectuer la mise en forme.
    Ce sont des requêtes dont les bases sont des fichiers Excel (voir des dossiers de fichiers .csv). Le résultat est donc aussi un fichier Excel utilisé par quelqu'un d'autre. Et tout effectuer sous forme de requête est bien plus efficace que de manipuler des "Range" Excel.
    J'utilise d'ailleurs des SELECT INTO pour m'affranchir de l'ouverture/fermeture des fichiers Excel.

    Il est peut avantageux de remplacer LEFT JOIN par un INNER JOIN. Tout cela dépend de ton application.
    En l'occurence, j'aurais aimé pousser le vice jusqu'à avoir la liste de mes clients, avec les différents numéros sur les colonnes adéquates, ou bien null si un numéro est manquant. Le INNER JOIN donne le même résultat que le FROM/WHERE. Le LEFT JOIN me raccourcit l'expression car pour un résultat identique avec les FROM/WHERE, il me faut faire l'UNION de plusieurs requêtes traitant de chacun de mes cas (N2.NUMERO IS NULL, etc).


    Pour Rei Ichido et tatayo : Désolé, j'ai débauché plus d'une 1/2 heure en retard vendredi pour faire ce message, donc il y avait peut-être quelques imperfections dues à mon impatience à décoller. De plus, c'est une copie visuelle de code d'un PC à un autre (pas Internet sur mon PC où je code), d'où les oublis probables. Néanmoins, je pensais que mes explications étaint suffisamment claires pour avoir droit à une réponse à mon problème.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Par défaut
    Citation Envoyé par seabs
    Ton SQL doit bien supporter l'instruction CASE
    J'ai remplacé le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CASE WHEN T.TYPE_NUMERO = 'FIXE' THEN T.NUMERO END AS NumeroFixe
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IIF(T.TYPE_NUMERO = 'FIXE',T.NUMERO,NULL) AS NumeroFixe
    Et ça fonctionne parfaitement.

    Il ne reste que l'erreur donnée par Waldar :
    Citation Envoyé par Waldar
    n'oubliez pas l'agrégat sur les numéros, actuellement votre requête renvoie deux lignes.
    Une idée ?

  8. #8
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Grouper par id_client, et dans les fonctions mettre un MAX ou un MIN (selon la façon dont le SGBD trie les null) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT C.NOM,
    MAX(IIF(T.TYPE_NUMERO = 'FIXE',T.NUMERO,NULL)) AS NumeroFixe,
    MAX(IIF(T.TYPE_NUMERO = 'MOBILE',T.NUMERO,NULL)) AS NumeroMobile
    FROM CLIENT C
             JOIN NUMERO T ON (C.ID_CLIENT = T.ID_CLIENT)
    GROUP BY c.id_client

    Edit : cela dit, je préfère largement la version à double jointure !

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 454
    Par défaut
    Essayez le même besoin avec quinze attributs, comparez les syntaxes des requêtes ainsi que les performances et dites-moi ensuite lequel vous préférez !

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Par défaut
    Citation Envoyé par Rei Ichido
    cela dit, je préfère largement la version à double jointure !
    Citation Envoyé par Waldar
    Essayez le même besoin avec quinze attributs, comparez les syntaxes des requêtes ainsi que les performances et dites-moi ensuite lequel vous préférez !
    Avec le SQL au travers du VBA Excel, la question ne se pose pas, puisqu'il m'était impossible d'ajouter dans le JOIN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND N1.TYPE_NUMERO = 'FIXE'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Expression JOIN non supportée
    En revanche, si la vitesse de la requête sera certainement plus rapide avec la solution MAX(IFF()) (seulement 2 tables à joindre, le reste est réalisé avec des UNION au travers du IIF), c'est aussi un peu moins lisible pour quelqu'un reprenant le code, à mon goût.

    Petite remarque : J'ai dû remplacer l'agrégation sur C.ID_CLIENT par C.NOM.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT C.NOM,
    MAX(IIF(T.TYPE_NUMERO = 'FIXE',T.NUMERO,NULL)) AS NumeroFixe,
    MAX(IIF(T.TYPE_NUMERO = 'MOBILE',T.NUMERO,NULL)) AS NumeroMobile
    FROM CLIENT C
             JOIN NUMERO T ON (C.ID_CLIENT = T.ID_CLIENT)
    GROUP BY C.NOM
    Sans cela, le moteur d'Excel m'envoyait bouler, à moins que je ne retire le C.NOM du SELECT.

    En tout cas, merci à tous, cela fonctionne exactement comme je le souhaite à présent !! Et ça m'a permis d'intégrer en prime le fonctionnement du IIF, donc c'est tout bénef !!

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/11/2009, 12h35
  2. LEFT JOIN SUR 2 TABLES EXTERNES
    Par DevServlet dans le forum JPA
    Réponses: 2
    Dernier message: 08/09/2009, 22h57
  3. left join sur deux tables !
    Par cLaSic dans le forum Requêtes
    Réponses: 6
    Dernier message: 16/04/2009, 09h57
  4. 2 LEFT JOIN sur une même table
    Par dakan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/10/2007, 13h51
  5. [MySQL] 2 LEFT JOIN sur même table
    Par bupocirk dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/07/2007, 16h53

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