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 PHP Discussion :

Ecrire une clause en fonction des choix dans le moteur de recherche


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut Ecrire une clause en fonction des choix dans le moteur de recherche
    Bonsoir,

    Pouvez vous m'aider svp ?

    Voilà je cherche la bonne façon de faire pour écrire ma requête.

    Actuellement j'ai 1 table "abonnes" et une table "abonnements" (liées entre elles)

    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
    --
    -- Structure de la table `abonnes`
    --
     
    CREATE TABLE IF NOT EXISTS `abonnes` (
      `id_abonne` int(11) NOT NULL AUTO_INCREMENT,
      `nom_abonne` varchar(32) NOT NULL,
      `age_abonne` date NOT NULL,
      `sexe_abonne` varchar(1) NOT NULL,
      PRIMARY KEY (`id_abonne`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
     
    --
    -- Contenu de la table `abonnes`
    --
     
    INSERT INTO `abonnes` (`id_abonne`, `nom_abonne`, `age_abonne`, `sexe_abonne`) VALUES
    (1, 'pierre', '1978-05-06', 'H'),
    (2, 'marie', '1988-02-09', 'F');
     
    --
    -- Structure de la table `abonnements`
    --
     
    CREATE TABLE IF NOT EXISTS `abonnements` (
      `id_abonnement` int(11) NOT NULL AUTO_INCREMENT,
      `nom_abonnement` varchar(255) NOT NULL,
      `abonne_abonnement` int(11) NOT NULL,
      PRIMARY KEY (`id_abonnement`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
     
    --
    -- Contenu de la table `abonnements`
    --
     
    INSERT INTO `abonnements` (`id_abonnement`, `nom_abonnement`, `abonne_abonnement`) VALUES
    (1, 'le monde', 1),
    (2, 'l''equipe', 1),
    (3, 'marie claire', 1),
    (4, 'figaro', 2),
    (5, 'lui', 1),
    (6, 'elle', 2);

    pour afficher tous mes abonnements et les abonnes correspondants j'ai fait ceci (ça affiche tout)

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM `abonnements` LEFT OUTER JOIN abonnes on id_abonne = abonne_abonnement

    Ca vous parait juste ? C'est quoi la différence avec le right outer join ?

    Mon vrai problème est que je ne sais pas comment écrire et intégrer ma clause where avec mon moteur de recherche.

    Si je sélectionne que les abonnes homme "H" ou que les abonnes femme "F" je ne sais pas comment ça se traduit dans ma requête.

    Même chose si on me demande de sélectionner les abonnes femme ou homme qui ont tel age (en fonction de la date de naissance)

    Merci de m'avoir lue et encore plus si vous pouvez m'aider

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Avant de construire ton modèle, tu dois te poser ces deux questions (entre autres):
    1. Peut-il y avoir un abonné sans abonnement (un ancien abonné par exemple, ou un futur abonné mais qui n'est pas encore décidé, un abonné dont le journal n'existe plus)?
    2. Peut-il y avoir un journal sans abonnés?


    Si la réponse est non pour ces deux questions (et que c'est bien le cas dans tes tables), dans ce cas que la jointure soit à gauche, à droite, interne ou externe, tu obtiendras le même résultat.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT INNER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT OUTER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    RIGHT OUTER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement

    produiront alors le même résultat (avec une variation de l'ordre pour la dernière requête):
    journal nom
    le monde pierre
    l'equipe pierre
    marie claire pierre
    lui pierre
    figaro marie
    elle marie


    Si par contre tu autorises un "abonné" à n'être abonné à rien du tout (ce qui est possible avec tes tables), disons "Paul", dans ce cas il n'apparaîtra pas avec une jointure interne mais va apparaître avec une jointure externe du coté de la table "abonnes" (OUTER inclus les éléments en dehors de la liaison, LEFT se rapporte à la table après l'instruction FROM, RIGHT à celle après JOIN), soit:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    RIGHT OUTER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement
    ou en plaçant la table "abonnes" à gauche:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnes
    LEFT OUTER JOIN abonnements
    ON abonnes.id_abonne = abonnements.abonne_abonnement

    qui donneront:
    journal nom
    le monde pierre
    l'equipe pierre
    marie claire pierre
    lui pierre
    figaro marie
    elle marie
    NULL paul



    Sinon ton modèle n'est pas idéal, car il va engendrer beaucoup de redondances. Imagine si tu as x abonnés au journal "Le Monde", alors ta table "abonnements" contiendra x fois la chaîne "le monde". Pour pallier à ce problème, il faut faire un modèle à trois tables: la table "abonne", la table "journal", la table "abonnement". La table "journal" ne devra contenir que le nom du journal et son id. La table "abonnement" contiendra juste deux clés étrangères: id_abonne, id_journal.

    Je te conseille de te plonger dans les tutoriels du site.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  3. #3
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    C'est super, merci beaucoup CosmoKnacki !!!

    L'idée était de dire : un abonnement a forcement un abonné.

    J'aurai pu gérer cela avec une table tierce, tu as raison.

    Par contre est-ce que tu sais comment écrire la requête de select avec une clause on va dire dynamique (c'est à dire quand on rajoute un critère dans le moteur de recherche)

    Par défaut j'ai ma requête (d'ailleurs pourquoi les alias AS ? On les réutilise où/pas ?)

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT INNER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement

    Imaginons que je sélectionne le critère "sexe" (donc "H" ou "F")

    Comment dois/puis-je intégrer cette clause WHERE abonnes.sexe_abonne = "H" à la volée ? C'est vraiment la syntaxe exacte qui me manque.

    Merci à toi.

    M_M

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    L'idée était de dire : un abonnement a forcement un abonné.
    Oui, ça ce voit à la clause NOT NULL de la colonne "abonnements.abonne_abonnement", mais avec une telle structure, rien n'empêche un enregistrement dans la table "abonnements" de se référer à un abonné qui n'existe pas. Tu devrais te pencher sur les contraintes d'intégrité.

    J'aurai pu gérer cela avec une table tierce, tu as raison.
    Tu le peux encore.

    Comment dois/puis-je intégrer cette clause WHERE abonnes.sexe_abonne = "H"
    Ajoute la à la fin de ta requête, je ne vois pas trop quel est le problème. Au passage, la colonne sexe tu peux la passer en CHAR au lieu de VARCHAR(1).

    d'ailleurs pourquoi les alias AS ? On les réutilise où/pas ?
    Tu en fais ce que tu veux, ils ne sont pas essentiels. Leurs buts sont de clarifier, simplifier une requête ou de faciliter l'accès aux résultats.

    NB: Si tu veux tester tes requêtes ou essayer de nouveaux modèles, je te conseille d'utiliser MySQL Workbench (gratuit), c'est mieux que de se galérer avec PHPMyAdmin.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    Merci

    En fait ma requête évolue en fonction des choix dans le moteur de recherche.

    Par défaut c'est cette requête qui est jouée :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT INNER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement

    mais si je trie les hommes et les femmes que dois-je écrire pour lui dire que ce critère existe ou a été demandée.

    Dans l'absolu ca va donner
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT INNER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement
    WHERE abonnes.sexe_abonne = "H"
    mais il me manque le truc pour dire que je dois écrire un where c'est quoi la façon de dire : si le filtre genre existe et s'il est = à "H" ou "F"

    Comment on l'écrit proprement à la volée si je puis dire ? Comment je passe de la première requête à la seconde de façon automatique ?

    M_M

  6. #6
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Non mais je vois vraiement pas ce qu'il y a de compliqué dans ton histoire. Rassure moi, tu as bien créé un formulaire permettant de saisir la demande de l'utilisateur? Si oui, il suffit de tester les valeurs renvoyées par ce formulaire dans un script php pour construire la requête et puis c'est tout. Si non, qu'est ce que tu attends pour le faire?
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  7. #7
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    Ca s'écrit comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $Rqt = "SELECT abonnements.nom_abonnement AS journal, abonnes.nom_abonne AS nom
    FROM abonnements
    LEFT INNER JOIN abonnes
    ON abonnes.id_abonne = abonnements.abonne_abonnement";
    if(isset($_GET["genre"]))
    {
    echo 'WHERE abonnes.sexe_abonne = "'.$_GET["genre"].'"';
    }
    C'est la bonne façon d'écrire la requête ?

  8. #8
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    j'ai trouvé ça aussi :

    solution 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( empty($variable) ) {
        $stmt = $this->_db->prepare("SELECT * FROM ki_cities");
    } else {
        $stmt = $this->_db->prepare("SELECT * FROM ki_cities WHERE id = :user");
        $stmt->bindValue(':user',$variable,PDO::PARAM_INT);
    }
    solution 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $stmt = $this->_db->prepare('SELECT * FROM `ki_cities` WHERE ((:user IS NULL) OR (`id` = :user));');
    $stmt->bindValue(':user', $variable, is_null($variable) ? PDO::PARAM_NULL : PDO::PARAM_INT);

    solution 3
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $sql = "SELECT * FROM authTable WHERE 1 = 1";
    if ($authName) {
    $sql .= " AND authName='$authName'";
    }
    if ($authCoun) {
    $sql .= " AND authCoun='$authCoun'";
    }
    if ($authSate) {
    $sql .= " AND authSate='$authSate'";
    }
    C'est vraiment comme ça qu'il faut faire ?

    M_M

  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Alors il y a à boire et à manger dans ce que tu proposes. Ce qu'il ne faut surtout pas faire c'est concaténer directement le contenu d'une variable qui vient de l'extérieur dans une requête (comme dans l'exemple 3), car c'est la porte ouverte aux injections SQL. Par contre, il faudra bien faire une concaténation à un moment ou à un autre pour ajouter la/les clauses WHERE:
    1. J'ajoute la clause WHERE 1=1 à la fin de ma requête (ou je l'ai écrite directement comme ça)
    2. Je teste si la valeur venue du formulaire existe avec isset, sinon je m'arrête ou je m'occupe des valeurs suivantes.
    3. Je vérifie qu'elle à bien une des valeurs autorisées. (pour le sexe "F" ou "H" mais pas "W" ou "choucroute garnie"), sinon je m'arrête ou je m'occupe des autres valeurs.
    4. J'ajoute ensuite à ma requête ' AND abonnes.sexe_abonne = :genre'
    5. Si j'ai d'autres valeurs je recommence à 2), sinon je continue
    6. Je prépare ma requête (méthode prepare avec PDO ou mysqli)
    7. Je bind mes valeurs
    8. J'exécute ma requête
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  10. #10
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    Bonjour CosmoKnacki,

    Ok, oui je suis d'accord avec tout mais comment tu passes de la phase 3 et 4 ?

    Comment ça doit s'écrire concrètement ?

    M_M

  11. #11
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    Bonjour,

    T'as pas une idée ma grande saucisse de l'espace ?

    M_M

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    voici une méthode qui permet d'ajouter autant de critères qu'on veut à une requête.

    N.B. Tant qu'à passer par un formulaire, il faut privilégier la method="post".

    Les critères : le genre, le nom (pour l'exemple).
    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
    <?php
    // -----------------------------------------------------------
    // CLAUSE WHERE :
    	$clauseWhere	= array();
    	$pdoParams	= array();
    // ---------------------
    // Récupération : GENRE
    $genre_choisi = ( isset($_POST['genre']) )?	$_POST['genre'] : '';
     
    if( !empty($genre_choisi) ) // ou $genre_choisi != "W" (à adapter)
    {
    	$clauseWHERE[]	= " abonnes.sexe_abonne = :genre ";		// on NE met PAS de " AND " ici !)
    	$pdoParams[':genre']	= $genre_choisi;
    }
    // ---------------------
    // Récupération : NOM
    $nom_choisi = ( isset($_POST['nom']) )?	$_POST['nom'] : '';
     
    if( !empty($nom_choisi) ) 
    {
    	$clauseWHERE[]	= " abonnes.nom LIKE :nom ";		// on NE met PAS de " AND " ici !)
    	$pdoParams[':nom']	= '%'.$nom_choisi.'%';
    }
    // ---------------------
    // Construction du "WHERE... AND..."
    	$clauseWhere	= (empty($clauseWhere)) ? NULL : 'WHERE ' . implode(' AND ', $clauseWhere);
     
    // -----------------------------------------------------------
    // REQUETE
    $requete = "SELECT * FROM abonnes ". 	// (A ADAPTER au besoin)
    		$clauseWhere.
    		""; 	// ORDER... (A ADAPTER au besoin)
     
    // ---------------------
    // Préparation /execution
      try {
    	$pdo_select = $pdo->prepare($requete);
    	$pdo_select->execute($pdoParams);
      } catch (PDOException $e){ echo 'Erreur SQL : '. $e->getMessage().'<br/>'; die(); }
    // -----------------------------------------------------------
    Dernière modification par Invité ; 09/03/2016 à 14h25.

  13. #13
    Membre du Club
    Femme Profil pro
    Webmaster
    Inscrit en
    Avril 2014
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2014
    Messages : 61
    Points : 61
    Points
    61
    Par défaut
    Encore un grand merci sir jreaux62

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/01/2011, 09h34
  2. Réponses: 11
    Dernier message: 10/06/2008, 10h31
  3. Réponses: 5
    Dernier message: 08/05/2008, 21h44
  4. Variable qui évolue en fonction des choix dans formulaire
    Par stefou007 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 06/09/2005, 22h40

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