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 et clause dans table de droite


Sujet :

Langage SQL

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2005
    Messages
    489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2005
    Messages : 489
    Points : 171
    Points
    171
    Par défaut left join et clause dans table de droite
    Bonjour à tous,

    Voilà je bute sur une requête depuis un moment et je ne sais plus ou chercher...

    Je dispose surement d'un cas classique mais je ne m'en sors pas...

    En base, je dispose donc d'une table client (uui, nom, prenom, ...) et de tables adresses (id, ville, code_postal, ..., client_id) et contact (id, valeur, client_id, ..)

    Ma requête doit effectuer une recherche de clients dont les critères possibles sont le nom, le prénom, la ville, valeur du contact, sachant qu'un client ne dispose pas forcément d'adresse renseignée ou de contact

    ma requête actuelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    select clientcont3_.valeur, client0_.id as id1_6_, client0_.activite_commerce_interdite as activite2_6_, client0_.civilite_id as civilit23_6_, client0_.code_magasin as code_mag3_6_, client0_.createur_id as createu24_6_, client0_.date_anniversaire as date_ann4_6_, client0_.date_creation as date_cre5_6_, client0_.date_creation_sys as date_cre6_6_, client0_.date_mariage as date_mar7_6_, client0_.date_modification as date_mod8_6_, client0_.date_modification_sys as date_mod9_6_, client0_.date_suppression as date_su10_6_, client0_.entite_id as entite_25_6_, client0_.genre_client as genre_c11_6_, client0_.modificateur_id as modific26_6_, client0_.nom as nom12_6_, client0_.origine as origine13_6_, client0_.prenom as prenom14_6_, client0_.societe as societe15_6_, client0_.supprimeur_id as supprim27_6_, client0_.taux_remise as taux_re16_6_, client0_.type_client as type_cl17_6_, client0_.type_envoi_courrier as type_en18_6_, client0_.type_envoi_email as type_en19_6_, client0_.type_envoi_sms as type_en20_6_, client0_.type_libre as type_li21_6_, client0_.uuid as uuid22_6_ 
    from client client0_ 
    inner join entite entite1_ on client0_.entite_id=entite1_.id 
    left outer join client_adresse clientadre2_ on (clientadre2_.client_id=client0_.id) and (upper(clientadre2_.ville) like ('%'||upper('')||'%') or upper(clientadre2_.code_postal) like ('%'||upper('')||'%'))   
    left outer join client_contact clientcont3_ on (clientcont3_.client_id=client0_.id) and (clientcont3_.valeur is not null and clientcont3_.valeur like ('%'||'@mail'||'%')) 
    where (entite1_.numero_licence in ('ZB230EC')) 
    and (upper(client0_.nom) like ('%'||upper('')||'%')) 
    and (client0_.prenom is null or upper(client0_.prenom) like ('%'||upper('')||'%')) 
    and (client0_.date_creation_sys is null or client0_.date_creation_sys>='2017-01-01') 
    and (client0_.date_modification_sys is null or client0_.date_modification_sys>='2017-01-01') 
    and (client0_.date_suppression is null or client0_.date_suppression>='9999-12-12')
    Dans cette exemple, je recherche des clients disposant d'une adresse email contenant '@mail'.

    Le problème est que le résultat me retourne 2 clients, mais 2 client n'ayant aucune adresse email... donc il n'aurait pas du me sortir ces clients là. Et je dispose de clients répondant à cette demande, mais pas ressorti dans cette requête ...

    Auriez-vous une solution pour cette requête?

    Merci

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    J'imagine que dans vos upper('') il y a des paramètres ?

    Essayez quelque chose de ce genre :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        select cli.id
             , ...
          from client         as cli
    inner join entite         as ett on ett.id        = cli.entite_id
     left join client_adresse as adr on adr.client_id = cli.id
     left join client_contact as ctc on ctc.client_id = cli.id
         where ett.numero_licence = 'ZB230EC'
           and cli.id in (select client_id
                            from client_contact
                           where valeur like '%@mail%'
                           union all
                          select client_id
                            from client_adresse
                           where upper(ville) like '%' || upper('') || '%'
                           union all
                          select client_id
                            from client_adresse
                           where upper(code_postal) like '%' || upper('') || '%'
                           union all
                          select id
                            from client
                           where upper(nom) like '%' || upper('') || '%'
                           union all
                          select id
                            from client
                           where upper(prenom) like '%' || upper('') || '%');
    L'idéal serait même de ne pas construire les blocs du union all s'il n'y a pas de saisie utilisateur.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2005
    Messages
    489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2005
    Messages : 489
    Points : 171
    Points
    171
    Par défaut
    les paramètres sont optionels, donc les UPPER sont parfois réalisé sur des chaînes vides.

    Donc pas le choix que les Union d'après ce que j'ai compris?

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Je n'ai pas assez d'informations, mais vous pouvez très bien appeler une fonction / procédure stockée qui construit le bon SQL en fonction des paramètres reçus.
    Attention aux upper, ça peut vous causer des soucis dans la non utilisation d'index. Il vaut mieux utiliser des collations.

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2005
    Messages
    489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2005
    Messages : 489
    Points : 171
    Points
    171
    Par défaut
    Merci pour votre réponse.

    Qu'appelez vous des collations? j'utilise le UPPER pour comparer les chaînes de caractères

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Ah oui, ici j'ai mis des UNION ça va traiter vos paramètres comme des OU logiques.
    Si vous voulez des ET logiques il faut utiliser INTERSECT.

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Pour les collations : https://sqlpro.developpez.com/cours/...er/collations/
    Quel est votre SGBD ?

  8. #8
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2005
    Messages
    489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2005
    Messages : 489
    Points : 171
    Points
    171
    Par défaut
    Je travaille sur une base PostgreSql, et mon application est avec Java, Spring et JPA

  9. #9
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    En ré-écrivant la requête pour ne pas avoir de conditionnelles "fixes" dans la clause ON, qu'est-ce que ça donne ?

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    with 	clientcont3_ as
    ( select client_id, valeur
    	from client_contact
    	where clientcont3_.valeur like '%'||'@mail'||'%' 
    	/* and clientcont3_.valeur is not null*/
    )
    select clientcont3_.valeur
    	, client0_.id as id1_6_
    	, client0_.activite_commerce_interdite as activite2_6_
    	, client0_.civilite_id as civilit23_6_
    	, client0_.code_magasin as code_mag3_6_
    	, client0_.createur_id as createu24_6_
    	, client0_.date_anniversaire as date_ann4_6_
    	, client0_.date_creation as date_cre5_6_
    	, client0_.date_creation_sys as date_cre6_6_
    	, client0_.date_mariage as date_mar7_6_
    	, client0_.date_modification as date_mod8_6_
    	, client0_.date_modification_sys as date_mod9_6_
    	, client0_.date_suppression as date_su10_6_
    	, client0_.entite_id as entite_25_6_
    	, client0_.genre_client as genre_c11_6_
    	, client0_.modificateur_id as modific26_6_
    	, client0_.nom as nom12_6_, client0_.origine as origine13_6_
    	, client0_.prenom as prenom14_6_
    	, client0_.societe as societe15_6_
    	, client0_.supprimeur_id as supprim27_6_
    	, client0_.taux_remise as taux_re16_6_
    	, client0_.type_client as type_cl17_6_
    	, client0_.type_envoi_courrier as type_en18_6_
    	, client0_.type_envoi_email as type_en19_6_
    	, client0_.type_envoi_sms as type_en20_6_
    	, client0_.type_libre as type_li21_6_
    	, client0_.uuid as uuid22_6_ 
    from 				client 				client0_ 
    	inner join 		entite 				entite1_ 
    			on client0_.entite_id=entite1_.id 
    	left outer join	client_adresse 		clientadre2_ 
    			on 	(clientadre2_.client_id=client0_.id) 
    				/*and 
    				(upper(clientadre2_.ville) like ('%'||upper('')||'%') or upper(clientadre2_.code_postal) like ('%'||upper('')||'%'))   */
    	left outer join clientcont3_ 
    			on (clientcont3_.client_id=client0_.id)
    where (entite1_.numero_licence in ('ZB230EC')) 
    	and (upper(client0_.nom) like ('%'||upper('')||'%')) 
    	and (client0_.prenom is null or upper(client0_.prenom) like ('%'||upper('')||'%')) 
    	and (client0_.date_creation_sys is null or client0_.date_creation_sys>='2017-01-01') 
    	and (client0_.date_modification_sys is null or client0_.date_modification_sys>='2017-01-01') 
    	and (client0_.date_suppression is null or client0_.date_suppression>='9999-12-12')
    Le savoir est une nourriture qui exige des efforts.

Discussions similaires

  1. [MySQL] left join et clause where
    Par jeanmichel.lovichi dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 18/10/2013, 14h57
  2. [MySQL] 2 left join sur le meme table
    Par adamess dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 08/07/2010, 20h56
  3. 2 LEFT JOIN sur une même table
    Par dakan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/10/2007, 13h51
  4. left join multiple sur grosses tables
    Par hn2k5 dans le forum Requêtes
    Réponses: 6
    Dernier message: 30/11/2005, 16h10
  5. [Performance] LEFT JOIN vs SELECT dans une boucle (PHP)
    Par frochard dans le forum Requêtes
    Réponses: 4
    Dernier message: 28/10/2005, 17h45

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