Partage
  • Partager sur Facebook
  • Partager sur Twitter

récupérer des item disponible selon une période

Sujet résolu
    17 septembre 2021 à 14:04:32

    Bonjour à tous,

    Je suis sur Symfony 5.3.7.

    L'objectif:

    lorsque l'utilisateur entre une période de date (entrée et sortie), cela lui retourne les chambre disponible à cette date. 

    Ce que j'ai pour l'instant:

    Tout l'inverse, la fonction me retourne les appartements correspondant à cette période. Ceux ne l'ayant pas ne figurent pas dans la liste. 

    Quel est l'astuce qui permet de pouvoir lui dire l'inverse?

    Du code, du code, du code:

    public function findByAvailableRooms($start, $leave)
        {
            
            $qb = $this->createQueryBuilder('r')
            
                ->join('r.bookings', 'b')
                ->where('b.startDate <= :startDate ')
                ->andWhere('b.leaveDate >= :leaveDate')
    
                ->orWhere('b.startDate >= :startDate')
                ->andWhere('b.leaveDate <= :leaveDate')
    
                ->orWhere('b.startDate >= :startDate')
                ->andWhere('b.leaveDate >= :leaveDate')
                ->andWhere('b.startDate <= :leaveDate')
    
                ->orWhere('b.startDate <= :startDate')
                ->andWhere('b.leaveDate <= :leaveDate')
                ->andWhere('b.leaveDate >= :startDate')
    
    
                ->setParameter('startDate', $start)
                ->setParameter('leaveDate', $leave);
    
    
    
            $query = $qb->getQuery();
    
            $results = $query->getResult();
    
            return $results;}

    Merci beaucoup

    -
    Edité par Frigalou 17 septembre 2021 à 14:40:53

    • Partager sur Facebook
    • Partager sur Twitter
      17 septembre 2021 à 15:13:22

      si tu as l'inverse de ce que tu attends, il faut sans doute "inverser" les conditions.

      (vérifier peut-être les priorités des orwhere et andwhere (on fait les or avant après les and ? "a or b and c" = "(a or b) and c" ou "a or (b and c)"; je pense qu'on est dans le dernier cas)

      Tu peux aussi écrire tes conditions dans les where si ça peut être plus clair=> par exemple where("a<b OR a>c ")

      • Partager sur Facebook
      • Partager sur Twitter
        17 septembre 2021 à 15:27:28

        Merci pour ta réponse.

        Dans symfony J'ai vu que and() n'existait pas. mais andWhere() oui. J'ai changé mon code pour celui ci dessous. J'obtiens le même résultat. 

        Pour les conditions j'ai changé les <= en >= et inversement, mais j'obtiens encore le même résultats.(EDIT: ce qui ne sert strictement à rien au cas où, donc je ne pense pas que tu me parlais de ca quand tu me disais d'inverser les conditions)

        Le code modifié (mais avec les conditions non modifié):

        $qb = $this->createQueryBuilder('r')
                    ->join('r.bookings', 'b')
                    ->where('b.startDate <= :startDate AND b.leaveDate >= :leaveDate')
                    ->orWhere('b.startDate >= :startDate AND b.leaveDate <= :leaveDate')
                    ->orWhere('b.startDate >= :startDate AND b.leaveDate >= :leaveDate AND b.startDate <= :leaveDate')
                    ->orWhere('b.startDate <= :startDate AND b.leaveDate <= :leaveDate AND b.leaveDate >= :startDate')
        
                    ->setParameter('startDate', $start)
                    ->setParameter('leaveDate', $leave);

        Après oui effectivement quand j'ai vu que ca faisait l'inverse, je me suis dis qu'il fallait que j'inverse les chose evidemment, du coup j'ai essayé plein de choses dont inverser les conditions, inverser les :startDate et :leaveDate, 

        Merci de ton aide encore une fois.

        -
        Edité par Frigalou 17 septembre 2021 à 15:49:08

        • Partager sur Facebook
        • Partager sur Twitter
          17 septembre 2021 à 17:15:58

          inverser une condition, c'est aussi inverser leur relation. l'inverse de 0<a<100 (a>0 ET a<100) c'est (a<=0 OU a>=100)

          Mais en fait, ce n'est vraiment ce que tu as besoin de faire ici. ta table bookings ne contient que les chambres réservées ? donc elle ne connait pas les autres ?

          tu dois avoir une table des chambres ? il faut retourner cette table en excluant la liste retournée par ta requête actuelle

          • Partager sur Facebook
          • Partager sur Twitter
            17 septembre 2021 à 17:56:34

            oui ma table booking contient les champs: id, startDate, leaveDate, Room.

            $results me retourne un tableau avec les chambre réservé pour la date selectionné. voila ce que j'obtiens depuis le debut:

            Si l'utilisateur sélectionné une date ou il y a deja des reservations:

            S'il n'y a pas de reservation a cette date:

            Je ne comprend pas comment lui exclure la liste retourné par la requête actuelle ou lui inverser ca

            -
            Edité par Frigalou 17 septembre 2021 à 17:59:19

            • Partager sur Facebook
            • Partager sur Twitter
              17 septembre 2021 à 18:53:15

              sélectionner les chambres qui ne sont pas dans le retour de ma requête. en SQL, un truc du genre

              SELECT * FROM Rooms as r JOIN bookings as b ON r.id = b.room WHERE b.room NOT IN (SELECT b.room FROM b WHERE [conditions sur les dates])

              (je suppose que Rooms est le nom de table des chambres, et qu'elle a un champ id qui est repris dans la table bookings; le 2nd select est ta requête actuelle)

              • Partager sur Facebook
              • Partager sur Twitter
                17 septembre 2021 à 22:48:54

                Salut

                Si jamais, tu as andX() et orX() qui prennent en paramètre autant d'expressions que souhaité.

                • Partager sur Facebook
                • Partager sur Twitter
                  17 septembre 2021 à 23:57:40

                  Merci pour vos réponses. Je n'avais jamais entendu parlé du NOT IN. Ca à l'air bien pratique, mais je vais l'adapter à la manière symfony. je vois que c'est possible mais j'ai encore un peu de mal à comprendre certaine chose sur la construction des requête avec les méthodes Symfony. Je vois plein d'exemple avec les subquery et tout ca, mais j'ai encore un peu du mal a savoir par quoi je remplace certaines choses. Je vous dirai si ca a marché et comment je l'ai adapté.

                  Merci Ymox pour le andx() et orx(). Je viens d'aller voir la documentation sur le site de doctrine, et j'avoue j'ai pas trop compris ce que ca faisait concrêtement au juste, donc je vais continuer mes recherche et voir si ca peut m'être utile et en quoi .

                  EDIT:

                  il semblerait que ce sois quelque chose qui ressemble à ca, mais qui n'est pas tout à fait ça. 

                  public function findByAvailableBookings($start, $leave)
                      {
                          $sqb = $this->createQueryBuilder('b')
                              ->select('room')
                              ->from('booking', 'b')
                              ->where('b.startDate <= :startDate AND b.leaveDate >= :leaveDate')
                              ->orWhere('b.startDate >= :startDate AND b.leaveDate <= :leaveDate')
                              ->orWhere('b.startDate >= :startDate AND b.leaveDate >= :leaveDate')
                              ->orWhere('b.startDate <= :startDate AND b.leaveDate <= :leaveDate');
                          
                          $qb = $this->createQueryBuilder('r')
                              ->select('r')
                              ->from('room', 'r')
                              ->join('booking', 'b', 'ON', 'r.id=b.room')
                              ->where($sqb->expr()->notIn('b.room', $sqb));
                  
                          $query = $qb->getQuery();
                  
                          $results = $query->getResult();
                  
                  
                          return $results;
                      }

                  Dans les exemple que j'ai pu voir, ils construisent d'abord la subQuery pour l'ajouter à la query.

                  A ce stade je me trouve avec une erreur comme 

                  Object of class Doctrine\ORM\EntityManager could not be converted to string

                  Si quelqu'un a une idée... Merci

                  -
                  Edité par Frigalou 18 septembre 2021 à 1:03:35

                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 septembre 2021 à 21:24:32

                    Si jamais, createQueryBuilder('b') dans le BookingRepository implique les lignes 4 et 5 du dernier code ci-dessus.

                    L'erreur que tu mentionnes, elle survient vraiment dans le code fourni ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 septembre 2021 à 22:29:38

                      Oui, j'avais fais un copié collé en direct du code et de l'erreur. (j'ai retesté pour voir avec le code que j'avais fournis ici et j'ai bien la même erreur). Mais je pense pour le coup savoir que ce code ne peu pas fonctionner car à la ligne 15 where($sqb... ne semble pas etre bon.

                      Je suis apparemment obligé de lui passer un paramètre. au createQueryBuilder('b'). j'ai essayé avec r, ou un autre alias qui n'existait pas. ca n'a pas marché. mais en tout cas si je ne met rien il me demande quelque chose. 

                      J'ai eu des aides pour corriger un peu, dont umfred d'ailleur,  mais pour l'instant ca ne fonctionne pas encore. avec la pate de tous on devrai y arriver ^^).

                      Je le place au cas ou (on sait jamais si je suis bon à une petite bétise de rien pret):


                      public function findByBookings($start, $leave): array
                          {
                              $qb = $this->createQueryBuilder('r');
                              $subquery =
                                  $qb->select('DISTINCT(b.room)')
                                  ->from('booking', 'b')
                                  ->where('b.startDate <= :startDate AND b.leaveDate >= :leaveDate')
                                  ->orWhere('b.startDate >= :startDate AND b.leaveDate <= :leaveDate')
                                  ->orWhere('b.startDate >= :startDate AND b.leaveDate >= :leaveDate')
                                  ->orWhere('b.startDate <= :startDate AND b.leaveDate <= :leaveDate')
                                  ->getDQL();
                              var_dump($qb->getDQL());
                        
                              $query = $qb
                                  ->select('r')
                                  ->from('room', 'r')
                                  ->leftjoin('r.bookings', 'rb')
                                  ->where($qb->expr()->notIn('b.room', $subquery))
                                  ->setParameter('startDate', $start)
                                  ->setParameter('leaveDate', $leave);
                      
                              $query = $qb->getQuery();
                      
                              $results = $query->getResult();
                      
                      
                              return $results;
                      
                          }

                      Mais cette correction que l'on m'as fournie me génère une autre erreur que je n'arrive pas a corriger mais qui me fais penser que ca avance, (en espérant ne pas me tromper). La voici:

                      [Semantical Error] line 0, col 62 near 'booking b, room': Error: Class 'booking' is not defined.

                      Voilà pour les avancé qui en sont finalement toujours au même point! :D

                      Merci pour votre aide encore et toujours! :)


                      J'ai aussi essayé de cette façon :

                      public function findByBookings1($start, $leave): array
                          {
                              $dql = '
                          SELECT * 
                          FROM room AS r 
                          JOIN booking AS b ON r.id = b.r 
                          WHERE b.r NOT IN 
                          (SELECT b.room 
                           FROM booking AS b
                           WHERE 
                             b.startDate <= :startDate AND b.leaveDate >= :leaveDate OR WHERE 
                             b.startDate >= :startDate AND b.leaveDate <= :leaveDate OR WHERE
                             b.startDate >= :startDate AND b.leaveDate >= :leaveDate OR WHERE
                             b.startDate <= :startDate AND b.leaveDate <= :leaveDate
                          ) AS subq
                          ';
                              $query = $this->getEntityManager()
                                  ->createQuery($dql)
                                  ->setParameter('startDate', $start)
                                  ->setParameter('leaveDate', $leave);
                      
                              $results = $query->getResult();
                      
                      
                              return $results;
                      
                          }

                      Pas conluant non plus.

                      -
                      Edité par Frigalou 18 septembre 2021 à 23:07:14

                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 septembre 2021 à 0:26:25

                        Non, ce que je voulais dire avec createQueryBuilder(), c'est que par défaut l'alias qui doit lui être donné va aussi impliquer les deux lignes que tu as mises en-dessous — et si tu as dû spécifier parce que c'est pour une autre entité que celle du repository dans lequel tu travailles, il y a un petit souci de logique à mon sens.

                        Ensuite, quand tu utilises from() pour une autre entité, il faut lui donner le nom complet de la classe, pas juste une chaîne de caractères que tu décides qu'elle doit être la bonne. Mettre \Truc\Chose\Bidule::class plutôt que 'ceQueJePenseQueJePeuxMettre'.

                        Sinon, les chambres qui sont disponibles sont celles qui ont une réservation s'arrêtant avant l'arrivée ou commençant après le départ.
                        Autre manière de faire : compter les réservations qui se terminent entre l'arrivée et le départ, qui commencent entre l'arrivée et le départ, et ajouter une clause having().

                        • Partager sur Facebook
                        • Partager sur Twitter
                          19 septembre 2021 à 0:44:40

                          Alors ce que j'ai compris de ce que tu dis, je devrai faire un code comme celui la?

                          public function findByBookings($start, $leave): array
                              {
                          
                                  $subquery =
                                      $this->createQueryBuilder('b')
                                      ->select('b.room')
                                      ->from(booking::class, 'b')
                                      ->where('b.startDate <= :startDate AND b.leaveDate >= :leaveDate')
                                      ->orWhere('b.startDate >= :startDate AND b.leaveDate <= :leaveDate')
                                      ->orWhere('b.startDate >= :startDate AND b.leaveDate >= :leaveDate')
                                      ->orWhere('b.startDate <= :startDate AND b.leaveDate <= :leaveDate')
                                      ->getDQL();
                          
                                  
                                  $query =
                                      $this->createQueryBuilder('r')
                                      ->select('r')
                                      ->from('room', 'r')
                                      ->leftjoin('r.bookings', 'rb')
                                      ->where($this->createQueryBuilder('b')->expr()->notIn('b.room', $subquery))
                                      ->setParameter('startDate', $start)
                                      ->setParameter('leaveDate', $leave);
                          
                                  $query = $this->createQueryBuilder('r')->getQuery();
                          
                                  $results = $query->getResult();
                          
                          
                                  return $results;
                          }

                          Cela me retourne bien les chambres disponible, mais aussi quand elles ne le sont pas ^^. j'ai toutes les chambre tout le temps ^^
                           Mais y a du mieux! ^^

                          Je vais voir ce que je peu faire avec having() 

                          (ps: tu fais comment pour encadrer comme tu l'as fait pour having() ou les autre nom de méthodes?)

                          petite réflexion supplémentaire, au début le code que j'avais faisait juste exactement l'inverse de ce que je voulais. Est ce normal qu'il sois si compliqué de juste lui faire faire mot pour mot l'inverse? ne suis-je pas en train de m'enfoncer vers de faux problèmes?

                          La fonction que j'avais au début (et dont je me servirai pour d'autre chose du coup), retournait les appartements qui sont loués aux dates sélectionnées. Là je veux la même chose mais en disponible. Le "NOTIN" me semblait être une bonne solution, du moins il semble logique puisque c'est tout ceux qui sont pas dans la liste des appartements loués que je veux. Est ce qu'il n'y a pas un moyen plus simple de l'utiliser?

                          Qu'entend tu par compter les réservations? Cela vas me retourner les chambre disponible? ou le nombre de jour disponible? est ce que je vais pouvoir retourner un tableau de ma liste de chambre disponible?

                          Edit: Je viens de voir ça lorsque je fais sur la subquery un var_dump($this->createQueryBuilde('b')->getDQL()); J'ai ça comme réponse: "SELECT b FROM App\Entity\Room\Room b" donc les WHERE ne passent pas j'ai l'impression. et ce qui ne vas pas c'est qu'il fais un from Room la ou il faudrai un from Booking.


                          Et aussi je travaille dans le RoomRepository qui m'a été généré avec le RoomEntity par symfony. est ce que le problème peut venir de là? 


                          -
                          Edité par Frigalou 19 septembre 2021 à 1:54:51

                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 septembre 2021 à 10:31:46

                            Quitte à me répéter : dès que tu fais createQueryBuilder(…), cela implique aussi un SELECT lEntiteDuRepository, donc les select() et from() soit ne sont pas utiles, soit vont poser problème.

                            La négation d'une expression logique est parfois complexe, et il suffit d'oublier certains cas pour que ça pose problème. Bêtement, le contraire d'une comparaison A > B, c'est A <= B, tout comme le contraire de A => B est A < B, et oublier le signe égal peut poser problème.
                            Avec les manières que j'ai mentionnées, les chambres libres sont celles qui : n'ont pas de réservation

                            • s'arrêtant entre le début et la fin de celle qu'on tente de créer
                            • OU commençant entre le début et la fin de celle qu'on tente de créer

                            De ce point de vue : deux BETWEEN, un OR (ici on pourrait avoir un orX() plus pratique qu'un orWhere() du fait de ce qui suit), un NOT, et l'expression devrait faire ce qu'on attend.

                            -
                            Edité par Ymox 20 septembre 2021 à 14:12:03

                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 septembre 2021 à 12:40:41

                              Pour ton erreur "Sementical", c'est le nom qui n'était pas bon "booking" ne doit pas exister au contraire de "bookings"

                              Sinon tes paramètres sont à définir dans la 1ère requête (la sous-requête) et pas dans la seconde, sauf erreur de ma part.

                              -
                              Edité par umfred 20 septembre 2021 à 12:41:10

                              • Partager sur Facebook
                              • Partager sur Twitter
                                20 septembre 2021 à 13:18:19

                                Hello Ymox, merci encore!

                                j'essaie de bien comprendre ce que tu me dis et faire un code qui y ressemble. J'ai un peu de mal a comprendre si j'ai bien compris l'utilisation du orX().

                                Mais voici un code qui m'as l'air d'être a peu prêt ce que tu me conseil. je sais que c'est pas exactement ca puisqu'il ne marche pas.

                                le code: 

                                public function notBookedRooms($start, $leave)
                                    {
                                
                                        $subQueryBuilder = $this->createQueryBuilder('b');
                                        $conditions = array('b.startDate BETWEEN :startDate AND :leaveDate', 'b.leaveDate BETWEEN :startDate AND :leaveDate');
                                        $orX = $subQueryBuilder->expr()->orX();
                                        foreach ($conditions as $condition) {
                                            $orX->add($condition);
                                        };
                                
                                        $subQueryBuilder
                                            ->add('where', $orX)
                                            ->setParameter(':startDate', $start)
                                            ->setParameter(':leaveDate', $leave);
                                
                                        $queryBuilder = $this->createQueryBuilder('r');
                                        $query = $queryBuilder
                                            ->where($queryBuilder->expr()->notIn('room.bookings', $subQueryBuilder));
                                
                                        $results = $query->getQuery()->getResult();
                                
                                        return $results;
                                    }

                                l'erreur généré: 

                                Object of class Doctrine\ORM\EntityManager could not be converted to string

                                Ce que je comprend c'est que la chaine ne peu pas être convertit en string (oui c'est écrit) mais pour quand il traduit le DQL pour le transformer en requête SQL j'imagine? Mais je veux aussi comprendre qu'elle est la source de cette erreur.

                                Je suis encore débutant alors il y a des choses que j'ai encore du mal a comprendre. Pardon si je te fais répéter ou que je ne comprenne pas certaine chose. Ca va venir.

                                Aussi, j'ai l'impression que Symfony rend la chose plus compliqué à ce niveau là que d'écrire en entier sa requête SQL.

                                Sois je m'égard, sois je me rapproche, et le problème c'est que je sais pas dans lequel des deux je me situe.



                                Hello umfred, 

                                Merci umfred effectivement j'ai vu ca plus tard et j'ai replacé les setParameter() au bon endroit. Par contre si j'ai bien suivi ton conseil, je n'ai pas de résultat.

                                En revanche je suis arrivé à var_dumper la requête (j'y arrivais pas avant, je sais pas pourquoi) et ca me donne ça: 


                                SELECT FROM App\Entity\Room\Room r WHERE room NOT IN(SELECT DISTINCT(bookings) FROM r.bookings b WHERE (b.startDate <= :startDate AND b.leaveDate >= :leaveDate) OR (b.startDate >= :startDate AND b.leaveDate <= :leaveDate) OR (b.startDate >= :startDate AND b.leaveDate >= :leaveDate) OR (b.startDate <= :startDate AND b.leaveDate <= :leaveDate))"


                                Est ce que ce que tu voulais dire devrai ressembler à cette requête?



                                -
                                Edité par Frigalou 20 septembre 2021 à 13:56:27

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  20 septembre 2021 à 14:26:13

                                  Ma proposition permettrait de n'avoir qu'une requête et plus de sous-requête.

                                  public function notBookedRooms($start, $leave)
                                  {
                                      $qb = $this->createQueryBuilder('r');
                                      $qb ->innerJoin('r.bookings', 'b')
                                          ->where($qb->expr()->not($qb->expr()->orX(
                                              $qb->expr()->between('b.startDate', ':startDate', ':leaveDate'),
                                              $qb->expr()->between('b.leaveDate', ':startDate', ':leaveDate')
                                          )))
                                          ->setParameter(':startDate', $start)
                                          ->setParameter(':leaveDate', $leave);
                                  
                                      return = $qb->getQuery()->getResult();
                                  }

                                  Là, c'est dans le cas où toutes les chambres ont au moins une réservation. Pour gérer le cas des chambres qui n'en auraient pas, c'est là que having() interviendrait.

                                  public function notBookedRooms($start, $leave)
                                  {
                                      $qb = $this->createQueryBuilder('r');
                                      $qb ->addSelect('count(b.id) AS number')
                                          ->leftJoin('r.bookings', 'b', $qb->expr()->not($qb->expr()->orX(
                                              $qb->expr()->between('b.startDate', ':startDate', ':leaveDate'),
                                              $qb->expr()->between('b.leaveDate', ':startDate', ':leaveDate')
                                          )))
                                          ->groupBy('r.id')
                                          ->having($qb->expr()->eq('number', $qb->expr()->litteral(0))
                                          ->setParameter(':startDate', $start)
                                          ->setParameter(':leaveDate', $leave);
                                  
                                      $results = $qb->getQuery()->getResult();
                                   
                                      return $results;
                                  }

                                  A tester et adapter niveau syntaxe, mais l'esprit y est (donc il ne devrait pas y avoir de grosses modifications à effectuer).

                                  -
                                  Edité par Ymox 20 septembre 2021 à 14:32:17

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    20 septembre 2021 à 14:35:47

                                    euh non, c'est un "bordel" dans la sélection du nom des colonnes et des tables là
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      20 septembre 2021 à 14:50:06

                                      Merci beaucoup pour ta réponse Ymox , j'étais complétement passé a coté de comment on s'en servait du orX(), apparemment ^^.

                                      Pour le premier code, j'ai un comportement un peu particulier. Je m'explique:

                                      Il marche très bien parfait, je fais quelques essaie, j'ai que les chambre disponible au dates indiqué c'est ce que je voulais,  puis d'un coup, il me sort toutes mes rooms, tout le temps, jour réservé ou non. pourtant il marchait très bien juste avant.

                                      normalement un code quand il fonctionne et qu'on y touche plus il doit faire tout le temp la même chose non?

                                      Je parviens je ne sais pas comment à le refaire fonctionner, puis re... Ca vous à déjà fait ca? pourquoi? 

                                       Mais merci car je comprend beaucoup mieux et j'ai appris aussi!

                                      Pour le deuxième code, je suis encore en train d'essayer de le faire marcher. Je ne renie en aucun cas la qualité de ton code hein ^^ il est justement parfait. Et j'ai pas eu grand chose a retoucher en effet. 

                                      Juste les setParameter() que vs code n'aime pas à cet endroit. j'ai toujours pas réussi à trouver sa place à l'heure où je vous parle. 

                                      -
                                      Edité par Frigalou 20 septembre 2021 à 19:20:06

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        20 septembre 2021 à 23:04:38

                                        umfred a écrit:

                                        euh non, c'est un "bordel" dans la sélection du nom des colonnes et des tables là

                                        Précise, s'il te plaît ?

                                        Frigalou a écrit:

                                        Juste les setParameter() que vs code n'aime pas à cet endroit. j'ai toujours pas réussi à trouver sa place à l'heure où je vous parle.

                                        Il manque une parenthèse fermante sur la ligne du having().

                                        -
                                        Edité par Ymox 20 septembre 2021 à 23:05:21

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          21 septembre 2021 à 0:09:45

                                          Ymox a écrit:

                                          Il manque une parenthèse fermante sur la ligne du having().

                                          Oui oui je l'avais rajouté et j'ai aussi enlevé un t a 'litteral(). en faite je me trouve avec l'erreur :

                                          Too many parameters: the query defines 0 parameters and you bound 2

                                          Et j'arrive pas a la corrigé, mais je tente ^^. je me dis les setParameter() dans ce cas sont liées aux condition qui sont dans le leftJoin(). Alors j'ai tenter de corriger en les plaçant ici:

                                          $qb->addSelect('count(b.id) AS number')
                                                      ->leftJoin('r.bookings', 'b', $qb->expr()->not($qb->expr()->orX(
                                                          $qb->expr()->between('b.startDate', ':startDate', ':leaveDate'),
                                                          $qb->expr()->between('b.leaveDate', ':startDate', ':leaveDate'),
                                                          $qb->setParameter('startDate', $start),
                                                          $qb->setParameter('leaveDate', $leave)
                                                      )))

                                          Mais ca me dis 'non autorisé dans ce contexte'


                                          Et je pense que umfred devait parler de ma requête SQL bien pas belle juste quelque message en dessus ^^

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            21 septembre 2021 à 0:15:44

                                            Heu, pourquoi ai-je l'impression que tu as déplacé les setParameter() pour les mettre dans le orX()) ? C'est comme si tu disais «  J'aimerals les chambres où (ceci ou cela ou définis le paramètre :startDate et le paramètre leaveDate) ». setParameter() doit être appelé en dehors du leftJoin() comme je l'avais mis…

                                            Frigalou a écrit:

                                            Et je pense que umfred devait parler de ma requête SQL bien pas belle juste quelque message en dessus ^^

                                            Ah, si c'est bien ça, alors au temps pour moi  :ange:

                                            Edit

                                            J'ai retrouvé le seul cas avéré que j'aie rencontré où l'éditeur de code était dans les choux alors que le code était valide : ici

                                            -
                                            Edité par Ymox 21 septembre 2021 à 0:23:29

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              21 septembre 2021 à 0:27:41

                                              Tu as cette impression car tu es quelqu'un qui vois bien. c'est effectivement ce que je disais. En faite avec ce code tel quel j'ai cette erreur:

                                              public function notBookedRooms($start, $leave)
                                                  {
                                                      $qb = $this->createQueryBuilder('r');
                                                      $qb->addSelect('count(b.id) AS number')
                                                          ->leftJoin('r.bookings', 'b', $qb->expr()->not($qb->expr()->orX(
                                                              $qb->expr()->between('b.startDate', ':startDate', ':leaveDate'),
                                                              $qb->expr()->between('b.leaveDate', ':startDate', ':leaveDate')
                                                          )))
                                                          ->groupBy('r.id')
                                                          ->having($qb->expr()->eq('number', $qb->expr()->literal(0)))
                                                          ->setParameter(':startDate', $start)
                                                          ->setParameter(':leaveDate', $leave);
                                              
                                                      $results = $qb->getQuery()->getResult();
                                              
                                                      return $results;
                                                  }

                                              Too many parameters: the query defines 0 parameters and you bound 2


                                              C'est alors de là que j'ai tenté des trucs dont essayer de placer les setParameter() vers la ou les ":start" et ":leave" sont.

                                              J'ai même tenté de placer directement $start à la place de ':start' et pareil pour l'autre. Bon j'ai testé pc on sait jamais mais c'est pas concluant non plus.

                                              Ymox a écrit:

                                              j'ai retrouvé le seul cas avéré que j'aie rencontré où l'éditeur de code était dans les choux alors que le code était valide : ici

                                              Oui mais la c'est que le setParameter() soit souligné en rouge, je n'ai plus rien de souligné en rouge dans mon code, c'est juste Symfony qui m'indique cette erreur. Je ne pense pas que ce sois PHP intelephense. Au passage moi pour mes routes je fais que des annotations. 

                                              Mais c'est claire que ca doit pas arriver souvent un IDE dans les choux ^^

                                              -
                                              Edité par Frigalou 21 septembre 2021 à 0:48:42

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                21 septembre 2021 à 1:29:37

                                                Ah, je me suis fait avoir  :D

                                                Le troisième paramètre de leftJoin() doit être \Doctrine\ORM\Query\Expr\Join::WITH, et ce que j'ai mis en troisième dans mes exemples de code doit être décalé en quatrième.

                                                Nota bene : quand avec un code tu n'as pas d'erreur signalée par ton éditeur de code (et que celui-ci ne se trompe pas, évidemment, mais c'est justement rare), mais que tu en as une quand tu exécutes ledit code, le problème n'est pas dans la syntaxe, mais dans l'utilisation des éléments utilisés. Donc déplacer des éléments ailleurs ne va pas résoudre le souci, il faut plutôt voir ce qui pourrait manquer ou être en trop.

                                                -
                                                Edité par Ymox 21 septembre 2021 à 1:32:25

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  21 septembre 2021 à 14:16:20

                                                  Ymox a écrit:

                                                  Nota bene : quand avec un code tu n'as pas d'erreur signalée par ton éditeur de code (et que celui-ci ne se trompe pas, évidemment, mais c'est justement rare), mais que tu en as une quand tu exécutes ledit code, le problème n'est pas dans la syntaxe, mais dans l'utilisation des éléments utilisés. Donc déplacer des éléments ailleurs ne va pas résoudre le souci, il faut plutôt voir ce qui pourrait manquer ou être en trop.

                                                  Oui c'est pour ca que j'avais rajouté une parenthèse et enlevé un "t" à literal. mon ide ne me signalais plus d'erreur après. C'est directement symfony qui me disait l'erreur dès que je chargeais la page ^^

                                                  Le troisième paramètre de leftJoin() doit être \Doctrine\ORM\Query\Expr\Join::WITH, et ce que j'ai mis en troisième dans mes exemples de code doit être décalé en quatrième.

                                                  Alors, voila: j'ai corrigé comme ca, mais la j'ai un tableau vide tout le temps. j'ai bien le use en haut de ma class et en regardant comment on l'intégrai bah j'ai fait ca:

                                                  public function notBookedRooms($start, $leave)
                                                      {
                                                          $qb = $this->createQueryBuilder('r');
                                                          $qb->addSelect('count(b.id) AS number')
                                                              ->leftJoin('r.bookings', 'b', join::WITH,  $qb->expr()->not($qb->expr()->orX(
                                                                  $qb->expr()->between('b.startDate', ':startDate', ':leaveDate'),
                                                                  $qb->expr()->between('b.leaveDate', ':startDate', ':leaveDate')
                                                              )))
                                                              ->groupBy('r.id')
                                                              
                                                              ->having($qb->expr()->eq('number', $qb->expr()->literal(0)))
                                                              ->setParameter(':startDate', $start)
                                                              ->setParameter(':leaveDate', $leave);
                                                  
                                                          $results = $qb->getQuery()->getResult();
                                                  
                                                          return $results;
                                                      }

                                                  C'est bien là que tu voulais que je le mette?



                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    21 septembre 2021 à 14:36:16

                                                    Oui, c'est bon. Montre-nous la requête SQL qui est générée, s'il te plaît.

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      21 septembre 2021 à 14:39:10

                                                      Voici: "SELECT r, count(b.id) AS number FROM App\Entity\Room\Room r LEFT JOIN r.bookings b WITH NOT((b.startDate BETWEEN :startDate AND :leaveDate) OR (b.leaveDate BETWEEN :startDate AND :leaveDate)) GROUP BY r.id HAVING number = 0"
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        21 septembre 2021 à 14:48:16

                                                        C'est la requête DQL, pas SQL

                                                        Edit

                                                        Mais au temps pour moi, il faut enlever le not en fait si on utilise having() comme ça  :-°

                                                        -
                                                        Edité par Ymox 21 septembre 2021 à 14:51:26

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          21 septembre 2021 à 15:14:26

                                                          Ca y eesst!!!!!!!!!!!!!!!!!! Merci t'es le meilleur! Ca marche tellement bien!!! :D

                                                          Pour la requête SQL, je suis encore en train de chercher comment je la génère pc j'en aurai besoin que ce sois pour cette fonction ou une autre. Je pensais que $qb->getDQL() la générait, mais a ce que tu me dis c'est pas ca donc.. Mais en la regardant j'avais l'impression que c'était ca. Qu'as tu vu qui t'as fait dire que c'était pas ça?

                                                          Je manque évidemment d'expérience merci de me faire par de la tienne, et du temps que tu y a passé aussi. 

                                                          C'est bon cette fonction est plié je crois que maintenant je peu partir à la retraite tranquille! :p

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            22 septembre 2021 à 0:20:19

                                                            Frigalou a écrit:

                                                            Pour la requête SQL, je suis encore en train de chercher comment je la génère pc j'en aurai besoin que ce sois pour cette fonction ou une autre. Je pensais que $qb->getDQL() la générait, mais a ce que tu me dis c'est pas ca donc.. Mais en la regardant j'avais l'impression que c'était ca. Qu'as tu vu qui t'as fait dire que c'était pas ça?

                                                            Ben fort logiquement, la syntaxe de ce que tu donnes n'est pas du SQL valide, et en plus la méthode que tu as utilisée s'appelle getDQL() alors qu'il y a une méthode getSQL()

                                                            Normalement, avec Symfony quand tu es en mode développement et que tu arrives sur une page, il y a un onglet Doctrine dans la barre de débogage, et cet onglet affiche les requêtes DQL effectuées pour la page, les requêtes SQL ainsi que les paramètres utilisés pour leur exécution.

                                                            N'oublie pas de signaler ton sujet comme étant résolu, il y a un bouton prévu pour ça en haut du sujet, pas très loin du titre.

                                                            -
                                                            Edité par Ymox 22 septembre 2021 à 0:21:38

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              22 septembre 2021 à 11:16:58

                                                              Pour le getSQl il me semblait bien mais elle ne  resortait jamais dans la complétion quand je le mettais comme j'ai fais pour le getDQL() soit, $qb->getDQL. en faite fallait que je fasse $qb->getQuery->getSQL(). J'étais encore juste a coté. mais c'est bien ca me fait apprendre. 

                                                              Merci encore pour tout et à un prochain ticket! ;)

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              récupérer des item disponible selon une période

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown