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

PHP & Base de données Discussion :

Requête double, rédaction.. [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Par défaut Requête double, rédaction..
    Bonjour à tous et toutes,
    et merci de votre aide.

    Je rencontre un souci de rédaction d'une requête, qui me permet d'afficher un tri.
    Ma structure de tables :
    j'ai plusieurs tables : item, champ, et valeur_champ_item qui fait le lien entre l'item, le champ, et sa valeur.
    Par exemple : l'item "employe_1" a un champ "prenom" attribué, dont la valeur_champ_item est "gérard", et un champ nom attribué avec la valeur Durand.

    dans une requête de tri je souhaite afficher par exemple tous les employés dont la valeur prénom (id_champ_item 60) est vide. ce qui donne :
    ... AND (asso_valeur_champ_item.id_champ_item=60 AND asso_valeur_champ_item.valeur='') -> ça fonctionne.

    Là où j'ai un souci, c'est quand je demande un tri avec DEUX valeurs :
    ... AND (asso_valeur_champ_item.id_champ_item=60 AND asso_valeur_champ_item.valeur='') AND (asso_valeur_champ_item.id_champ_item=65 AND asso_valeur_champ_item.valeur='')

    Mon résultat est 0, alors que je sais que 4 items sont concernés.

    Je pense que le problème vient du fait que je demande deux fois des attributions de valeur_champ_item. J'ai mis des parenthèses pour bien délimiter le fait que je demande (id_champ_item=60 AND asso_valeur_champ_item.valeur='') ET AUSSI (id_champ_item=65 AND asso_valeur_champ_item.valeur='')

    Auriez-vous une idée ?

    Merci par avance,

    PF

  2. #2
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    Bonjour,

    C'est compliqué de pouvoir apporter de l'aide avec des bribes de code (de requête dans ce cas-ci ^^)

    Mais ce que je peux dire, c'est que s'il faut comparer plusieurs valeurs d'une même colonne (asso_valeur_champ_item), il faut soit faire plusieurs requêtes; soit loader plusieurs fois la même table avec des JOIN; il faut ensuite comparer la première valeur par rapport à la "première" table; et la seconde valeur par rapport à la "seconde" table

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM ma_table AS t1
    LEFT JOINT ma_table_de_cles AS c1 ON c1.ID = t1.ID
    LEFT JOINT ma_table_de_cles AS c2 ON c2.ID = t1.ID
    WHERE c1.ma_cle = 'prenom' AND c1.valeur = '' AND c2.ma_cle = 'nom' AND c2.valeur = ''

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 188
    Par défaut
    Bonjour,

    Je dirai qu'il faut faire autant de liaisons entre les tables que tu as de critères de sélections.

    par exemple
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM  maTable 
    INNER JOIN asso_valeur_champ_item as asso_valeur_champ_item1 ON maTable.id=asso_valeur_champ_item1.id
    INNER JOIN asso_valeur_champ_item as asso_valeur_champ_item2 ON maTable.id=asso_valeur_champ_item2.id 
    WHERE (id_champ_item=60 AND asso_valeur_champ_item1.valeur='')  AND (id_champ_item=65 AND asso_valeur_champ_item2.valeur='')

    je ne connais pas le nom des champs etc.. de ta base mais c'est le principe.

  4. #4
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Par défaut
    Bonjour,
    C'est un problème de logique.

    "ET AUSSI" : dans la requête, ce sera OR
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    ... AND ( (condition 1) OR (condition 2) ) AND ...
    Les parenthèses ont aussi leur importance.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ... 
    AND (
       (asso_valeur_champ_item.id_champ_item=60 AND asso_valeur_champ_item.valeur='')
       OR
       (asso_valeur_champ_item.id_champ_item=65 AND asso_valeur_champ_item.valeur='')
    )
    ...
    Ne pas hésiter à indenter le code, pour la lisibilité et le débogage.

  5. #5
    Membre averti
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2014
    Messages : 24
    Par défaut
    Bonjour et merci beaucoup de votre aide, c'est chouette de ne pas se sentir toute seule !

    @wehtam et @darkstar123456 :
    mon problème ne réside pas au niveau de la jointure.
    Concrètement la forme de la requête qui me pose problème se situe dans une seule et unique table.

    Mes tables sont :
    • Employes : les employés
    • champ_item : les critères possibles pour les employés
    • asso_valeur_champ_item : table qui contient l'association des valeurs des critères avec les employés. Par exemple : critère "permis caces" : 1 pour oui, critère "permis grue", 1 pour oui.


    donc j'ai dans la table asso_valeur_champ_item des lignes du type :

    • id_employe : 1 par exemple.
    • id_champ_item : 27 (par exemple, car c'est l'id du critère permis caces)
    • valeur : 1 ou 0


    • id_employe : 2 par exemple.
    • id_champ_item : 27
    • valeur : 1 ou 0


    • id_employe : 1 par exemple.
    • id_champ_item : 7 (par exemple, car c'est l'id du critère permis grue)
    • valeur : 1 ou 0


    etc.

    En Français ma requête problématique donnerait :
    Sélectionne dans la table " asso_valeur_champ_item " tous les employés dont l'"id_champ_item" 27 a pour valeur '1' ET dont l'"id_champ_item" 7 a pour valeur '1'
    pour sélectionner ceux qui ont le permis caces ET AUSSI le permis grue.


    ---

    @jreaux62 : Je ne connaissais pas la syntaxe "AND OR", est-ce une erreur dans ta réponse ? cela génère une erreur
    Fatal error: Call to a member function fetch_assoc() on boolean in ...
    ---

    j'ai testé en dur ma requête:
    si je mets juste :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') --> pour avoir ceux qui ont le permis caces
    j'ai 29 résultats.

    si je mets juste :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1') --> pour avoir ceux qui ont le permis grue
    j'ai 29 résultats (ce sont les mêmes qui ont le permis grue et le caces).

    mais si je mets :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') AND (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1')
    ou
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    AND ((asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') AND (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1'))
    je devrais avoir 29 résultats car ce sont les mêmes items qui ont ces valeurs pour ces critères, mais j'ai 0 résultats.

    Peut-être que je devrais essayer de faire des requêtes imbriquées du style
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * from asso_valeur_champ_item WHERE  (id_champ_item=27 AND valeur = '1')
    ... WHILE(mes resultats des id_employe qui ont le caces){
        select * from asso_valeur_champ_item WHERE  (id_champ_item=7 AND valeur = '1') AND id_asso_valeur_champ_item=$row[id_employe]
        ... WHILE(){
        ...etc.
    Mais j'ai une trentaine de tris qui peuvent être possibles, voir plus car la création de critères n'est pas limitée et je trouve ça moyennement propre comme requête, et potentiellement lent...

    Qu'en pensez-vous ?

  6. #6
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    Bonjour,

    Vous dites que tout ce situe dans une seule et unique table, et puis vous listez "Mes tables sont :"

    En tout cas, les 2 solutions (celle de @jreaux62, ainsi que celle de @wehtam et moi -qui avons donné la même-), fonctionnent et dépendent à la fois de la structure de la DB et de ce qu'on cherche.

    mais si je met :
    AND (asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') AND (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1')
    ou
    AND ((asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') AND (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1'))
    je devrais avoir 29 résultats car ce sont les mêmes items qui ont ces valeurs pour ces critères, mais j'ai 0 résultats.
    C'est 2 requêtes sont exactement identiques : en logique, pour qu'une condition AND soit vraie, elles doivent toutes êtres vraies. Du coup, les parenthèses n'ont aucune incidence.

    Si vous ne trouvez pas de résultat c'est parce que vous chercher des employés qui ont la valeur nom ET prénom à X (1 ici)
    Est-ce vraiment ça que vous cherchez ? Parce que ce n'est pas parce que 3 employés ont le prénom "Alfred" et que 2 employés ont le nom "Tartampion", qu'il y a 5 "Alfred Tartampion" dans l'entreprise. Il est même probable qu'il y en ait aucun.
    Il faut alors inclure un OR comme l'a fait @jreaux62 (le AND OR est une coquille)

    Ca donnerait ceci :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    AND ((asso_valeur_champ_item.id_champ_item=27 AND asso_valeur_champ_item.valeur = '1') OR (asso_valeur_champ_item.id_champ_item=7 AND asso_valeur_champ_item.valeur = '1'))
    Et ici, les parenthèses ont de l'importance !!

    PS : Ma première solution inclus des jointures car, je me trompe peut-être, mais il me semble qu'il est moins gourmand de faire des jointures et de n'avoir que des AND dans sa requête plutôt que d'avoir des OR qui sont normalement plus gourmands

  7. #7
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Par défaut
    oups...

    @jreaux62 : Je ne connaissais pas la syntaxe "AND OR", est-ce une erreur dans ta réponse ?
    oui, une erreur de copier-coller (pas relu/vu la fin de la ligne car j'étais sur ma mini-tablette ).
    C'est juste OR.

    Par contre, je n'avais pas bien saisi la problématique de base...
    j'ai plusieurs tables : item, champ, et valeur_champ_item qui fait le lien entre l'item, le champ, et sa valeur.
    et asso_valeur_champ_item ???

    Il faut faire des JOINTURES (INNER JOIN,...) entre les tables, et leur mettre des ALIAS, pour éviter les confusions de champs (si même nom dans plusieurs tables).


    N.B. AU LIEU DE BAVARDER, tu aurais mieux fait de montrer :
    • la structure des TABLES (sérieux... elle s'appellent vraiment "item","champ","..." ?)
    • La REQUETE (complète)

    On aurait gagné du temps.

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

Discussions similaires

  1. [PHP 5.3] Soucis avec le résultat d'une requête (double boucles while)
    Par beegees dans le forum Langage
    Réponses: 7
    Dernier message: 31/05/2010, 22h26
  2. Résultat de requête doublé
    Par ZeDave dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 07/02/2008, 16h08
  3. Problème : Requête double les enregistrements !
    Par Aost dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 22/06/2006, 17h44
  4. requète double en 1 fois
    Par Yoshio dans le forum Débuter
    Réponses: 10
    Dernier message: 15/01/2006, 23h37
  5. [Requête] Requête double, "OU" entre requêtes.
    Par muphin dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 21/06/2005, 15h04

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