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

Symfony PHP Discussion :

Symfony 5 : query builder avec plusieurs innerjoin et clauses where


Sujet :

Symfony PHP

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 156
    Points : 136
    Points
    136
    Par défaut Symfony 5 : query builder avec plusieurs innerjoin et clauses where
    Bonjour à tous,

    Je crée un query builder sur la table produit, pour récupérer mes produits selon différents critères.
    Dans les critères, il y a :
    - La gamme du produit, où je fais un innerjoin avec l'id et mets la condition sur les libellés de la gamme.
    - Les prix min et max, dans la table prixproduit, d'où un innerjoin sur l'id, et mes conditions sur le prix.
    - La qualité qui est dans ma table produit, où je sélectionne les valeurs 1 et 2.
    - L'indicateur sculpté où je sélectionne la valeur O.

    Voilà la partie de code dans mon controleur :
    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
    $qb = $entitymanager->getRepository('App:Produit')
    	->createQueryBuilder('produit')
    	->addSelect('produit');
     
    $choix_prix_min = 3;
    $choix_prix_max = 11;
    $filtre_gamme = ['PROTECTION', 'AUTRE'];
     
    $qb->innerJoin('App\Entity\Gamme', 'gamme', 'WITH', 'gamme.id = produit.idGamme');
    $qb->innerJoin('App\Entity\PrixProduit', 'prixproduit', 'WITH', 'prixproduit.idProduit = produit.id');
    $qb->add('where', $qb->expr()->in('gamme.nom', $filtre_gamme));
    $qb->andWhere($qb->expr()->gte('prixproduit.prix', $choix_prix_min))
    	->andWhere($qb->expr()->lte('prixproduit.prix', $choix_prix_max));
    $qb->add('where', $qb->expr()->in('produit.qualite', ['1', '2']));
    $qb->add('where', 'produit.sculpte = \'O\'');
     
    $q = $qb->orderBy('produit.dateCreation', 'desc')
    	->getQuery();
     
    $liste_produit = $q->getResult();
    Mon problème : Tous les where ne sont pas pris en compte.
    Avec le code ci dessus, ça filtre sur la qualité et l'indicateur sculpté, avec un 'ou' au lieu d'un 'et', mais pas sur la gamme.

    Si je mets mes where dans ce sens, en mettant la condition sur la gamme à la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $qb->innerJoin('App\Entity\Gamme', 'gamme', 'WITH', 'gamme.id = produit.idGamme');
    $qb->innerJoin('App\Entity\PrixProduit', 'prixproduit', 'WITH', 'prixproduit.idProduit = produit.id');
    $qb->andWhere($qb->expr()->gte('prixproduit.prix', $choix_prix_min))
    	->andWhere($qb->expr()->lte('prixproduit.prix', $choix_prix_max));
    $qb->add('where', $qb->expr()->in('produit.qualite', ['1', '2']));
    $qb->add('where', 'produit.sculpte = \'O\'');
    $qb->add('where', $qb->expr()->in('gamme.nom', $filtre_gamme));
    ça filtre bien sur la gamme, mais pas sur la qualité ni l'indicateur sculpté, où toutes les valeurs sont prises.

    J'ai essayé plein de trucs dans tous les sens, si ça se trouve j'ai raté un paramètre tout bête, mais là je ne vois plus rien !

    A moins que ça soit la conception de mon query builder qui ne va pas, mais je ne vois pas non plus.

    Merci d'avance pour votre aide.

  2. #2
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Bonjour,
    Si vous faites un $qb->getSql()

    Vous aurez la requête pour voir où est le souci.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 156
    Points : 136
    Points
    136
    Par défaut
    Bonjour,

    Merci beaucoup pour cette idée, je n'y avais pas pensé !

    En attendant, j'ai contourné mon problème en codant ma requête en dur comme une brute
    Et ça marche nickel !

    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
    $choix_prix_min = 3;
    $choix_prix_max = 11;
    $filtre_gamme_requete = "'PROTECTION', 'AUTRE']";
     
    $q = "select id_produit_id from produit";
    $q .= " inner join gamme on gamme.id = produit.id_gamme_id";
    $q .= " inner join prix_produit on prix_produit.id_produit_id = produit.id";
    $q .= " where prix_produit.prix >= ".$choix_prix_min;
    $q .= " and prix_produit.prix <= ".$choix_prix_max;
    $q .= " and gamme.nom in (".$filtre_gamme_requete.")";
    $q .= " and produit.qualite in ('1', '2')";
    $q .= " and produit.sculpte = 'O'";
    $q .= " order by produit.date_creation desc;";
     
    $stmt = $entitymanager->getConnection()->prepare($q);
    $stmt->execute([]);
    $liste_produit = $stmt->fetchAll();
    J'essaie dès que j'ai le temps de débuguer mon querybuilder, ça m'intrique, j'aimerais trouver où est le problème...

    Merci encore pour cette indication !

  4. #4
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Comme une brute ne veux pas dire comme un sauvage

    <troll>J'aime les requête hors ORM, c'est la vrai vie </troll>

    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
     
    <?php
    $choix_prix_min = 3;
    $choix_prix_max = 11;
    $filtre_gamme_requete = "'PROTECTION', 'AUTRE']";
     
    $q = "select id_produit_id from produit";
    $q .= " inner join gamme on gamme.id = produit.id_gamme_id";
    $q .= " inner join prix_produit on prix_produit.id_produit_id = produit.id";
    $q .= " where prix_produit.prix >= ? ";
    $q .= " and prix_produit.prix <= ? ";
    $q .= " and gamme.nom in (".$filtre_gamme_requete.")";
    $q .= " and produit.qualite in ('1', '2')";
    $q .= " and produit.sculpte = 'O'";
    $q .= " order by produit.date_creation desc;";
     
    $stmt = $entitymanager->getConnection()->prepare($q);
    $stmt->execute([$choix_prix_min,$choix_prix_max]);
    $liste_produit = $stmt->fetchAll();
    Par contre je reste perplexe sur ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    $filtre_gamme_requete = "'PROTECTION', 'AUTRE']";

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 156
    Points : 136
    Points
    136
    Par défaut
    Comme une brute ne veux pas dire comme un sauvage

    <troll>J'aime les requête hors ORM, c'est la vrai vie </troll>
    La FORCE est avec toi !!!

    Pour la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $filtre_gamme_requete = "'PROTECTION', 'AUTRE']";
    Tu as tout à fait raison (il m'a quand même fallu 2 minutes pour trouver la coquille ), je voulais écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $filtre_gamme_requete = "'PROTECTION', 'AUTRE'";

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 156
    Points : 136
    Points
    136
    Par défaut
    Rebonjour à tous,

    Je me suis repenché sur mon querybuilder, et je vois avec le getSql() qu'il me manque des critères.

    Voilà mon code maintenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $qb = $entitymanager->getRepository('App:Produit')
    ->createQueryBuilder('produit')
    ->innerJoin('App\Entity\Gamme', 'gamme', 'WITH', 'gamme.id = produit.idGamme')
    ->add('where', $qb->expr()->in('gamme.nom', $filtre_gamme));
    ->innerJoin('App\Entity\PrixProduit', 'prixproduit', 'WITH', 'prixproduit.idProduit = produit.id')
    ->andWhere($qb->expr()->gte('prixproduit.prix', $choix_prix_min))
    ->andWhere($qb->expr()->lte('prixproduit.prix', $choix_prix_max));
    ->add('where', $qb->expr()->in('produit.qualite', ['1', '2']));
    ->add('where', 'produit.sculpte = \'O\'');
     
    $q = $qb->orderBy('produit.dateCreation', 'desc')
    ->getQuery();
    dd($q->getSql());
    ça m'affiche (je zappe tous les champs du select qui font des km ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT p0_.id AS id_0, ... FROM produit p0_ INNER JOIN gamme g1_ ON (g1_.id = p0_.id_gamme_id) INNER JOIN prix_produit p2_ ON (p2_.id_produit_id = p0_.id) WHERE p0_.sculpte = 'O' ORDER BY p0_.date_creation DESC
    Il n'y a pas les where de mes 2 jointures (gamme et prixproduit), ni celui sur la qualité.
    Il n'y a dans ma requête générée que le dernier where de mon querybuilder.

    J'ai essayé dans tous les sens, je n'obtiens jamais tous mes where à la fois !
    Pourtant, je fais bien des add de mes where, ils devraient se cumuler, non ?
    Je me suis trompé sur ce point dans mon querybuilder ?

    Merci d'avance pour votre aide !

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2012
    Messages : 631
    Points : 1 220
    Points
    1 220
    Par défaut
    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
     
           /**
             * @var \Doctrine\ORM\QueryBuilder
             */
            $qb = $entitymanager->getRepository('App:Produit')
                ->createQueryBuilder('produit'); //ceci est un Objet QueryBuilder et sur cet dernier tu peux invoquer les méthodes expr(), join() ....
     
            $qb->innerJoin('App\Entity\Gamme', 'gamme', 'WITH', 'gamme.id = produit.idGamme')
                ->andWhere( $qb->expr()->in('gamme.nom', $filtre_gamme))
                ->innerJoin('App\Entity\PrixProduit', 'prixproduit', 'WITH', 'prixproduit.idProduit = produit.id')
                ->andWhere($qb->expr()->gte('prixproduit.prix', $choix_prix_min))
                ->andWhere($qb->expr()->lte('prixproduit.prix', $choix_prix_max))
                ->andWhere( $qb->expr()->in('produit.qualite', ['1', '2']))
                ->andWhere('produit.sculpte = \'O\'');
     
            $q = $qb->orderBy('produit.dateCreation', 'desc')
                ->getQuery();

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 156
    Points : 136
    Points
    136
    Par défaut
    Yes Merci beaucoup !!!

    J'étais persuadé, à tort, que add('where',...) et addWhere(...) étaient identiques, j'ai encore appris quelque chose aujourd'hui

    Merci encore, sujet résolu !

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

Discussions similaires

  1. [4.x] Query Builder avec différence entre date et heure
    Par yamatoshi dans le forum Symfony
    Réponses: 1
    Dernier message: 14/08/2020, 12h24
  2. Indexes avec < ou > dans la clause where ?
    Par Evocatii dans le forum Requêtes
    Réponses: 1
    Dernier message: 25/03/2008, 13h58
  3. Requêtes avec condition dans la clause where
    Par desmo dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 25/02/2008, 13h36
  4. Réponses: 0
    Dernier message: 16/11/2007, 09h05
  5. [SQL] Requete avec ordre correspondant à la clause WHERE
    Par yobogs dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 10/06/2007, 14h32

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