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

Requêtes MySQL Discussion :

Optimisation requete (MySQL 4.1 ou sup)


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Par défaut Optimisation requete (MySQL 4.1 ou sup)
    Bonsoir ,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT t1.id_adherent, t1.id_categorie, t1.nom, t1.prenom, t1.enseigne, t2.categorie, MIN(t3.numero) 
    FROM tbl_adherent AS t1 
    INNER JOIN tbl_categorie AS t2 ON t1.id_categorie = t2.id_categorie 
    INNER JOIN tbl_contact AS t3 ON t1.id_adherent = t3.id_adherent 
    WHERE t1.actif = 2 
    AND (t3.id_type_contact = 4 OR t3.id_type_contact = 6) 
    AND t3.numero REGEXP "[[.@.]]" 
    GROUP BY t1.id_adherent 
    ORDER BY t1.id_categorie, t1.id_adherent ASC
    Je cherche à recuperer les adherents qui ont un email, la requete rempli sa mission sauf que je la trouve bancale, et que je souhaiterai la perfectionner sur un point precis.
    - les adherents peuvent avoir plusieurs adresses email
    - les adresses email (t3.numero) sont enregistrées dans la table tbl_contact et elles ont un id_type_contact = 4; id_type_contact = 6 est un contact privé : ça peut être un numéro de téléphone ou un email, et s'agissant d'un traitement de données en back office, les emails sélectionnés dans la requête devrait être de type 6 par préférence (mais là je n'ai aucun contrôle )
    - je n'ai pas besoin de l'adresse email pour le traitement de la requête, elles sont récupérer sélectivement apres traitement d'un formulaire (établi depuis cette requête), mais je n'ai pas réussi a obtenir ce que je voulais sans passer par GROUP BY

    Pour ceux qui ont compris , (j'ai pas l'impression d'avoir été tres clair ), je voudrais savoir si il y a un moyen de récupérer les id, nom prénom etc... (unique) , des adhérents qui ont un email de type 6, puis sinon de type 4

    autre question quel est le plus rapide ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    AND t3.numero REGEXP "[[.@.]]" 
     
    ou
     
    AND t3.numero LIKE "%@%"
    c'est juste pour détecter l'email par rapport au No de téléphone, je reconnais que ça aurait plus malin de ma part de séparer les telephones privés et les email privés lors de la conception de la table... (je signale quand meme que je vérifie l'intégrité de l'emal lors de l'insertion dans la table avec PHP et une expression régulière heureusement un peu plus pointue ).

    Merci d'avance
    ++

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Bonjour,

    Effectivement, ça n'est pas optimalisé . Si tu voulais récupérer les id_type_contact par cette requête, et qu'il y a pour le même adhérent 4 et 6, c'est toujours 4 que renvoie la requête, or tu veux 6 (si j'ai bien compris ton problème ).

    Voilà donc une requête qui devrait faire ce que tu souhaites (d'abord 6 si ça existe, 4 sinon, et rien si il n'y a pas de mail) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT t1.id_adherent, t1.id_categorie, t1.nom, t1.prenom, t1.enseigne
    , t2.categorie
    , coalesce(t3.id_type_contact, t4.id_type_contact) as id_type_contact
    , coalesce(t3.numero, t4.numero) as numero
    FROM tbl_adherent t1
    INNER JOIN tbl_categorie t2 ON t1.id_categorie = t2.id_categorie
    LEFT JOIN tbl_contact t3 ON t1.id_adherent = t3.id_adherent AND t3.numero REGEXP "[[.@.]]" AND t3.id_type_contact = 6
    LEFT JOIN tbl_contact t4 ON t1.id_adherent = t4.id_adherent AND t4.numero REGEXP "[[.@.]]" AND t4.id_type_contact = 4
    WHERE t1.actif = 2
    AND COALESCE(t3.id_type_contact, t4.id_type_contact) IS NOT NULL
    ORDER BY t1.id_categorie, t1.id_adherent asc
    En mettant d'abord une jointure à gauche sur le type 6, on s'assure que c'est ce type là qui va sortir le premier.
    Je mets une jointure à gauche sur le type 4 également, parce que si il n'y a pas de mail du tout, on filtre dans le where pour virer ces lignes.

    J'espère que ça ira .

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre averti
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Par défaut
    Bon alors là j'hallucine un peu

    J'ai lu ta réponse tout a l'heure, je me suis dit : "mon explication était pas claire, il n'a pas compris, j'ai qu'une tbl_contact, pourquoi il fait t3.tbl_contact & t4.tbl_contact ? etc..."
    je mange , m'occupes l'esprit avec autre chose ,je me remets au boulot et je teste la requête du bout du clavier ("ca va planter" me disais-je ) et ben NON ça marche !!!

    En fait c'était pas exactement mon idée première, mais en réfléchissant un peu je vais finalement alléger mon code si j'utilise ta requête tel quelle.

    Ca n'empêche pas que du coup je ne comprends pas COALESCE (que je connaissais pas, j'ai lu le manuel ("Retourne le premier élément non-NULL de la liste :") , mais l'utilisation que tu en fais (t3 & t4) sème le doute dans mon esprit, et je comprends plus LEFT JOIN (ça je m'en sert, mais pas dans ce but ).

    Si tu peux m'expliquer les subtilités de la requete ... je mourrais pas idiot (et ça m'em...de de copier sans comprendre)

    Grand merci en tout cas
    ++

  4. #4
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    En fait, la première jointure à gauche (LEFT JOIN) permet de déterminer, pour chaque adhérent, si il y a un contact de type 6. Comme c'est un LEFT JOIN, si il n'y a pas de contact de type 6 avec mail, les champs t3 sont mis à NULL.
    Pareil avec la seconde jointure à gauche, sauf que ce coup-là ce sont les contacts de type 4.
    Ainsi, un contact de type 4 avec mail a les champs de t3 à NULL, et le champs de t4 remplis. Et un contact qui n'a pas de mail a les champs de t3 et de t4 à NULL.

    La fonction COALESCE, comme le dit la doc, renvoie la première occurence non null de la liste qui lui est passée en paramètre et renvoie NULL si tout est NULL.
    Du coup, pour un contact de type 6, COALESCE(t3.id_type_contact, t4.id_type_contact) équivaut à COALESCE(6,...), soit 6 (j'ai mis ... parce que comme il y a un type 6 d'entrée de jeu, on se fout de savoir si c'est aussi un contact de type 4 ou pas ).
    Pour un contact de type 4, ça équivaut à COALESCE(NULL, 4), soit 4.
    Et pour un contact qui n'a pas de mail, ça équivaut à COALESCE(NULL, NULL), soit NULL. C'est pour éliminer ce dernier cas que je mets le COALESCE dans la clause WHERE...

    J'espère que c'est plus clair .

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  5. #5
    Membre averti
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Par défaut
    C'est net et precis ; en fait par routine/habitude, j'oublie un peu trop souvent les valeurs NULL
    Merci ced

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

Discussions similaires

  1. [MySQL] optimisation requete mysql - while imbriquée
    Par Sbeuh dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 19/08/2010, 00h43
  2. Aide pour optimiser requete MYSQL
    Par roadruner dans le forum Requêtes
    Réponses: 4
    Dernier message: 26/03/2009, 11h24
  3. optimisation requetes mysql
    Par pas30 dans le forum Requêtes
    Réponses: 5
    Dernier message: 21/12/2007, 15h56
  4. [MySql] Optimisation Requete Balance Client
    Par rockclimber dans le forum Langage SQL
    Réponses: 3
    Dernier message: 06/11/2006, 14h55
  5. AIdez moi à optimiser cette requete MySQL SVP
    Par petozak dans le forum Langage SQL
    Réponses: 4
    Dernier message: 13/09/2005, 15h16

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