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 :

Requete SQL pour faire une recherche multi critères [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre du Club
    Femme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Novembre 2009
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur étude et développement

    Informations forums :
    Inscription : Novembre 2009
    Messages : 125
    Points : 55
    Points
    55
    Par défaut Requete SQL pour faire une recherche multi critères
    Bonjour,
    Je développe une application en php avec ZEND Framework, et j'aurai besoin de faire un moteur de recherche multi critères qui contiendra un champ texte pour saisir les mots clés et des listes déroulantes pour sélectionner en tenant compte du fait que le résultat peut s'afficher même si les autres choix ne sont pas fait.
    je n'arrive pas à afficher un résultat avec la requête que j'ai fait.
    j'aimerai un petit peu d'aide si quelqu'un peut bien le faire.
    Merci d'avance.

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Cela tient plus du PHP que de MySQL ton problème.
    Il faut créer la requête dynamiquement en PHP selon les choix faits par l'utilisateur et envoyer cette requête au SGBD.

    Si c'est ce que tu as fait mais que tu n'as pas le résultat attendu, commence par nous montrer la requête réellement envoyée au serveur et ce qu'elle est censée faire.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre du Club
    Femme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Novembre 2009
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur étude et développement

    Informations forums :
    Inscription : Novembre 2009
    Messages : 125
    Points : 55
    Points
    55
    Par défaut
    Merci pour ta réponse,
    alors je vais commencer par t'envoyer la requête que j'ai fait mais qui n'ai pas optimale car elle permet juste de sélectionner une offre en tapant un mot clés et en sélectionnant un contrat, un domaine et un lieu( je travaille sur le recherche des offres d'emplois) mon moteur de recherche contient les champs suivant: mots clés : champ text
    type de contrat : liste déroulante
    domaine d'activité : liste déroulante
    lieu : liste déroulante
    donc j'aimerai donner la possibilité de saisir plusieurs mots clés et prendre le fait de ne pas sélectionner un contrat ou un domaine ou un lieu( donc avoir un résultat même si tous les critères ne sont pas remplis)

    la fonction que j'ai utilisé est la suivant ( dans me modèle: je travail en MVC):

    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
    function getResultSearch($langCode,$motscles, $domaine , $local,$contrat){
                $chaine= $motscles;
     
                     $sc = "SELECT   {$this->alias}.`offreId`,
                                    {$this->alias}.`offreTitre`,
                                    {$this->alias}.`offreText`,
                                    {$this->alias}.`langCode`,
                                    o.`offreActive`,
                                    o.`offreRemuneration`,
                                    ct.`contratTitre`,
                                    dt.`domaineTitre`,
                                    lt.`localTitre`,
                                    o.`offreDateModif`
                            FROM  `{$this->table}` {$this->alias} 
                            INNER JOIN `recrutement_offre` o ON {$this->alias}.`offreId` = o.`offreId`
                            INNER JOIN `recrutement_domaine_text` dt ON o.`domaineId` = dt.`domaineId` AND dt.`langCode` = '{$langCode}'
                            INNER JOIN `recrutement_contrat_text` ct ON o.`contratId` = ct.`contratId` AND ct.`langCode` = '{$langCode}'        
                            INNER JOIN `recrutement_local_text` lt   ON o.`localId` = lt.`localId`     AND lt.`langCode` = '{$langCode}'
                            LEFT JOIN `thermidor_language` l ON  {$this->alias}.`langCode` = l.`langCode`    
                            WHERE {$this->alias}.langCode = '{$langCode}' 
                            AND  o.`offreActive` = 1 
                            AND {$this->alias}.offreMotsCles LIKE '%".$chaine."%'
                            AND o.domaineId = '{$domaine}' 
                            AND o.localId = '{$local}'  
                            AND o.contratId = '{$contrat}' 
                            GROUP BY {$this->alias}.`offreId`
                            ";
     
                if($rc = Database::execute_sql($sc))
                    return $this->parseResults($rc);
                }

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Ne t'embête pas avec les apostrophes inversées, ajoutées par phpMyAdmin quand il restitue les requêtes ; ça ne te sert à rien puisque tu as correctement nommé tes tables et colonnes sans espaces ni caractères qui pourraient être mal interprétés ni mots réservés SQL.

    mon moteur de recherche contient les champs suivant: mots clés : champ text
    type de contrat : liste déroulante
    domaine d'activité : liste déroulante
    lieu : liste déroulante
    Apparemment, le paramètre $langCode ne fait pas partie du formulaire ; on peut supposer qu'il a toujours une valeur.
    Comme les premières jointures sont des jointures internes, tu peux mettre les restrictions sur la langue dans le WHERE.

    Comme je l'ai dit dans mon précédent message, il faut construire la requête en fonction de l'existence d'une valeur dans les variables issues du formulaire.

    GROUP BY sans fonction de groupage (MAX, MIN, AVG, SUM, COUNT) ne sert pas à grand chose et je ne suis pas sûr que dans ton cas tu aies besoin d'un DISTINCT. En plus il faudrait que toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de groupage, c'est à dire ici toutes les colonnes du SELECT, figurent aussi dans le GROUP BY. Cette partie donnerait une erreur dans tout SGBD respectant mieux la norme SQL que le trop permissif MySQL !

    Globalement, cela devrait donner ce code :
    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
    49
    50
    51
    52
    53
    54
    function getResultSearch($langCode,$motscles, $domaine , $local,$contrat)
    {
      $chaine= $motscles;
     
      $sc = "
        SELECT {$this->alias}.offreId, 
          {$this->alias}.offreTitre, 
          {$this->alias}.offreText, 
          {$this->alias}.langCode, 
          o.offreActive, 
          o.offreRemuneration, 
          ct.contratTitre, 
          dt.domaineTitre, 
          lt.localTitre, 
          o.offreDateModif 
        FROM {$this->table} {$this->alias} 
        INNER JOIN recrutement_offre o ON {$this->alias}.offreId = o.offreId 
      ";
     
      if($domaine != '')
      {
        $join_domaine = "INNER JOIN recrutement_domaine_text dt ON o.domaineId = dt.domaineId ";
        $where_domaine = "AND dt.langCode = '{$langCode}' AND o.domaineId = '{$domaine}' ";
      }
     
      if($contrat != '')
      {
        $join_contrat = "INNER JOIN recrutement_contrat_text ct ON o.contratId = ct.contratId ";
        $where_contrat = "AND ct.langCode = '{$langCode}' AND o.contratId = '{$contrat}' ";
      }
     
      if($local != '')
      {
        $join_local = "INNER JOIN recrutement_local_text lt   ON o.localId = lt.localId ";
        $where_local = "AND lt.langCode = '{$langCode}' AND o.localId = '{$local}' "
      }
     
      $sc .= $join_domaine . $join_contrat . $join_local ."
        LEFT JOIN thermidor_language l ON  {$this->alias}.langCode = l.langCode    
        WHERE {$this->alias}.langCode = '{$langCode}' 
          AND  o.`offreActive` = 1 
        " . $where_domaine . $where_contrat . $where_local;
     
      if($chaine != '')
      {
        $sc .= "AND {$this->alias}.offreMotsCles LIKE '%".$chaine."%' ";
      }
     
     
      if($rc = Database::execute_sql($sc))
      {
        return $this->parseResults($rc);
      }
    }
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre du Club
    Femme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Novembre 2009
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur étude et développement

    Informations forums :
    Inscription : Novembre 2009
    Messages : 125
    Points : 55
    Points
    55
    Par défaut
    Merci pour cette réponse rapide,
    La requête que tu m'as donné marche très bien sauf qu'elle donne le même résultat que la mienne, ca que je n'arrive pas à faire c'est d'avoir un résultat en tapant juste un mot clés donc même en ne sélectionnant pas un domaine ou un contrat ou un lieu ou même en sélectionnant juste un des éléments d'une lista déroulante, en gros j'aimerai que la recherche donne un résultat en fonction du choix de l'utilisateur même si tous les critères ne sont pas remplis,( donc comment donner la possibilité d'avoir un résultat en ayant les listes déroulante null ou ayant un identifiant)
    Merci.

  6. #6
    Membre du Club
    Femme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Novembre 2009
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur étude et développement

    Informations forums :
    Inscription : Novembre 2009
    Messages : 125
    Points : 55
    Points
    55
    Par défaut
    j'ai oublié de parler du "langCode", c'est que les offres seront affichées dans plusieurs langues en fonction d'un drapeau qui sera sélectionné , en plus du fait que l'utilisateur peut taper un ou plusieurs mots cles, j'ai utilisé la fonction explode mais ça ne marche pas( j'ai fait $chaine= explode(" ",$motcles): une erreur fait que la requête ne donne aucun résultat.

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Si tu as un peu examiné mon code, tu auras constaté que la requête se construit dynamiquement en fonction de l'existence ou non d'une valeur pour les paramètres passés à la fonction. Au minimum, la requête est celle-ci :
    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
    SELECT {$this->alias}.offreId, 
        {$this->alias}.offreTitre, 
        {$this->alias}.offreText, 
        {$this->alias}.langCode, 
        o.offreActive, 
        o.offreRemuneration, 
        ct.contratTitre, 
        dt.domaineTitre, 
        lt.localTitre, 
        o.offreDateModif 
    FROM {$this->table} {$this->alias} 
    INNER JOIN recrutement_offre o ON {$this->alias}.offreId = o.offreId 
    LEFT JOIN thermidor_language l ON  {$this->alias}.langCode = l.langCode    
    WHERE {$this->alias}.langCode = '{$langCode}' 
        AND  o.`offreActive` = 1
    Je vois d'ailleurs qu'elle contient des colonnes potentiellement inexistantes donc mon code est encore à améliorer.

    À toi de voir comment sont alimentées les paramètres dans l'appel de la fonction, de tester leur valeur, ainsi que le texte exact de la requête, avec Zend_Debug, bref, de déboguer ton appli. Ici je n'ai donné que le principe mais c'est évidemment à ajuster au reste de l'appli.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  8. #8
    Membre du Club
    Femme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Novembre 2009
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur étude et développement

    Informations forums :
    Inscription : Novembre 2009
    Messages : 125
    Points : 55
    Points
    55
    Par défaut Merci pour votre remarque
    Après avoir retravailler la requête, finalement elle donne un bon résultat:
    elle est comme suit:
    Code sql : 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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    public function getResultSearch($langCode,$motscles, $domaine , $local,$contrat){
               $tmotscles = explode(" ",$motscles);
                 if($domaine != 0)
                 {
              $where_domaine = " AND o.domaineId = '{$domaine}' ";
              }
     
              if($contrat != 0)
              {
             $where_contrat = " AND o.contratId = '{$contrat}' ";
             }
     
             if($local != 0)
             {
             $where_local = " AND o.localId = '{$local}' ";
             }
     
             $sc = "
          SELECT {$this->alias}.offreId,
             {$this->alias}.offreTitre,
             {$this->alias}.offreText,
             {$this->alias}.langCode,
             o.offreActive,
             o.offreRemuneration,
             dt.domaineTitre,
             ct.contratTitre,
             lt.localTitre,
             o.offreDateModif
         FROM {$this->table} {$this->alias}
         INNER JOIN recrutement_offre o ON {$this->alias}.offreId = o.offreId
         INNER JOIN recrutement_domaine_text dt ON o.domaineId = dt.domaineId
              AND dt.langCode = '{$langCode}'
         INNER JOIN recrutement_contrat_text ct ON o.contratId = ct.contratId
              AND ct.langCode = '{$langCode}'
         INNER JOIN recrutement_local_text lt ON o.localId = lt.localId
             AND lt.langCode = '{$langCode}'
         LEFT JOIN thermidor_language l ON {$this->alias}.langCode = l.langCode
         WHERE {$this->alias}.langCode = '{$langCode}' AND o.`offreActive` = 1
             {$where_domaine}
             {$where_contrat}
             {$where_local}
              ";
     
               if(is_array($tmotscles))
               {
               foreach ($tmotscles as $mc){
               $sc .= " AND {$this->alias}.offreMotsCles LIKE '%{$mc}%'";
               }
     
               }
     
               $sc .= " GROUP BY {$this->alias}.`offreId` ";
     
                 if($rc = Database::execute_sql($sc))
                 {
                 return $this->parseResults($rc);
                  }
               }

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

Discussions similaires

  1. [PHP 5.3] POO - Créer méthode pour une recherche multi-critères
    Par almoha dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2014, 15h52
  2. requéte sql pour faire une recherche
    Par malone12 dans le forum Bases de données
    Réponses: 7
    Dernier message: 22/08/2010, 07h22
  3. REQUETE SQL pour faire une division
    Par slorgue dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 19/11/2008, 11h27
  4. requete sql pour faire un classement
    Par beezee dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/03/2006, 13h03
  5. problème SQL avec le tutoriel recherche multi critère
    Par qbihlmaier dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 05/12/2005, 19h33

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