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 :

Jointure sur plusieurs champs


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Jointure sur plusieurs champs
    Bonjour,

    Je dois croiser les informations de 2 tables, l'une contient un identifiant de dossiers au nom d'un utilisateur (home directories), l'autre des informations de secteur sur les utilisateurs, avec plusieurs colonnes login (par exemple, jdupont, ou jeandupont, ou jean.dupont, ou jedupon etc...) je dois croiser les informations entre les 2 tables, mais n'étant pas développeur je m'y perds un peu
    Soit T_FOLDER ma première table, et T_ID ma seconde table
    J'ai tenté ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select * from T_FOLDER F 
    left join T_ID I1 on F.Folder=I1.Login 
    left join T_ID I2 on F.Folder=I2.Login1 
    left join T_ID I3 on F.Folder=I3.Login2  
    left join T_ID I4 on F.Folder=I4.Login3
    left join T_ID I5 on F.Folder=I5.Login4
    Mais cela me renvoie toutes les données des 2 tables concaténées
    et ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select * from T_FOLDERS F
    left join T_ID I on F.Folder=I.Login
    or F.Folder=I.Login1
    or F.Folder=I.Login2
    or F.Folder=I.Login3
    or F.Folder=I.Login4
    Qui ne me rend simplement jamais la main, le volume d'info étant sans doute trop important.
    Il y a t'il une méthode pour cela? la première est elle la bonne si je filtre mon résultat par suite?

    Merci par avance pour votre aide

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Bonjour,

    C'est parce que tu fais un select *.
    Si tu veux garder seulement certaines colonnes, il faut les nommer.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT F.FOLDER, I1.LOGIN, I2.LOGIN, ...
    FROM ...
    Et en effet la deuxième solution est à proscrire (l'utilisation du or dans la jointure (ou même dans un filtre classique) n'utilisera pas les index selon le SGBD, ce qui aboutira à des temps de traitement conséquent comme tu as pu le remarquer)

  3. #3
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup pour ta réponse Emmanuel,

    effectivement cela règle mon premier problème qui est d'avoir des dupliquas dans mes colonnes, mais par contre je reste avec des lignes répliquées, ma table Folder fait 20000 lignes, j'ai 100000 lignes de résultat a la fin. Faut il que je fasse un tri a posteriori ou une modification de la requête pourrait me donner le résultat en une passage?

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Rebonjour,
    Cela arrive car tu as plusieurs lignes qui respectent la condition dans T_ID. Ta jointure n'est pas en 1,1. Concrètement, pour un F.FOLDER dans T_FOLDER, tu auras plusieurs I1.LOGIN (ou I2, I3, I4).

    As-tu une colonne qui permettrait de discriminer l'info ? Exemple typique : un CODE_STATUT à mettre à 1 pour assurer que la ligne est bien à prendre en compte.
    Tu peux faire un select * ... where F.FOLDER = ta_valeur_qui_a_plusieurs_lignes pour y voir plus clair et essayer de déterminer la colonne.

    Ensuite, rajouter la ou les colonnes qui permettent de filtrer dans la clause WHERE (ou dans la condition de jointure, vu que tu travailles avec des jointures externes ; mais ça m'étonnerait vu que tu travailles sur la même table)

  5. #5
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Re!

    Une nouvelle fois merci pour ton aide, effectivement je comprends maintenant d'où vient le problème. Je ne pense pas que je vais pouvoir discriminer des lignes, car je dois identifier tous les folders dont le nom match un ID, si dans l'extraction de l'annuaire, ils ont marqué 4 fois le même ID dans les champs Login1, Login2, Login3, Login4, je vais avoir 4 lignes. Dans certains cas je n'ai qu'un champ renseigné, d'autres fois 2 ou 0, il n'y a pas de règle malheureusement.

  6. #6
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Tu m'as mis sur une piste du coup, dans ma seconde table (celle ou il y a des dupliquas) il faut que le username soit non vide, mais je ne sais pas comment l'ecrire en sql vu que j'ai 4 alias: I1, I2, I3 et I4

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Re,

    Oui effectivement, c'est un problème de modélisation. SQLPro l'explique très bien dans ce billet sur la nécessité de normaliser les tables. Tu es en présence d'exactement le même cas qu'il présente avec les téléphones.

    Je suis en train de me demander si cette requête pourrait répondre à ton besoin. Note que je ne peux pas la tester dans l'immédiat, je ne connais pas son optimisation. Si quelqu'un passant par là pouvait confirmer ou infirmer...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ... 
    FROM T_FOLDER F 
    LEFT JOIN T_ID I ON F.Folder=COALESCE(I.Login, I.Login1, I.Login2, I.Login3, I.Login4)
    La fonction COALESCE() prend la première valeur non nulle. Ainsi, la jointure se ferait en premier sur Login, si Login est nul elle se fait sur Login1, sinon elle passe à Login2, et ainsi de suite.
    Vérifie bien que ça donne ce que tu veux obtenir si tu décides de l'utiliser.

    Edit : Oui, j'ai passé en left join le temps que tu écrives ton message

  8. #8
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Re
    Je vais regarder mais le pb de l'inner join, est qu'il ne va pas me renvoyer les lignes qui matchent, en fait je veux garder toute les lignes de la table gauche (T_FOLDERS) agrémentées des informations de la table T_ID, lorsqu'un dossier de la table T_FOLDER est matché dans l'un des champs login[1-4] de la table T_ID.
    Peut etre que cela n'est pas simple a realiser en SQL. Mais ton aide est déjà tres precieuse, et je vais regarder le lien que tu as posté

  9. #9
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Bonjour Emmanuel,

    Simplement pour te remercier de ton temps et ton aide sur le sujet, je pense qu'il n'y a pas de solution "simple" en effet, cela m'a néanmoins beaucoup aidé a comprendre le pourquoi du comment.

    Bonne journée a toi!

    Francois

  10. #10
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je n'avais pas vu que tu avais modifié la jointure, et du coup j'ai bien le nombre de ligne que je souhaite, pas toutes les informations, mais la table ID est effectivement très mal conçue. En tous cas cela solutionne en très grande partie mon problème, le truc du coalesce est nickel!

    Je vais donc te remercier une nième fois , et marquer ce post comme résolu!

    Francois

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

Discussions similaires

  1. Jointure externe sur plusieurs champs
    Par thanith dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 14/02/2013, 20h25
  2. Jointure externe sur plusieurs champs
    Par Vict0 dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 06/06/2011, 13h58
  3. Réponses: 3
    Dernier message: 04/06/2009, 15h49
  4. SQL : Jointure droite sur plusieurs champs
    Par Platon93 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 19/12/2006, 13h55
  5. [CR] Groupement dynamique sur plusieurs champs paramètrés
    Par CDRIK dans le forum SAP Crystal Reports
    Réponses: 8
    Dernier message: 07/06/2004, 17h55

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