Mysql
 sql >> Base de données >  >> RDS >> Mysql

Symfony2 - Doctrine2 QueryBuilder OÙ DANS le champ ManyToMany

Pour votre solution, vous pouvez utiliser COUNT(DISTINCT) avec HAVING et GROUP BY clauses

public function findByServices($services)
{
    $qb = $this->createQueryBuilder('hotel')
        ->addSelect('location')
        ->addSelect('country')
        ->addSelect('billing')
        ->addSelect('services')
        ->addSelect('COUNT(DISTINCT  services.id) AS total_services')
        ->innerJoin('hotel.billing', 'billing')
        ->innerJoin('hotel.location', 'location')
        ->innerJoin('location.city', 'city')
        ->innerJoin('location.country', 'country')
        ->innerJoin('hotel.services', 'services');
    $i = 0;
    $arrayIds = array();
    foreach ($services as $service) {
        $arrayIds[$i++] = $service->getId();
    }
    $qb->add('where', $qb->expr()->in('services', $arrayIds))
        ->addGroupBy('hotel.id')
        ->having('total_services = '.count($arrayIds))
        ->getQuery();
}

Dans la requête ci-dessus, j'ai ajouté une autre sélection pour compter les identifiants de service distincts pour chaque hôtel, c'est-à-dire

Ensuite, j'ai aussi besoin d'un groupe par pour ce compte, j'ai donc ajouté

Maintenant, voici la partie délicate car vous avez mentionné que vous avez besoin d'un hôtel qui a tous les identifiants de service comme les identifiants (1,2,3) donc les hôtels qui contiennent ces 3 services doivent être retournés lorsque nous utilisons dans ses performances ou son opération comme where servid_id = 1 or servid_id = 2 servid_id = 3 qui est exactement vous ne voulez pas le AND opération que l'hôtel doit avoir ces 3 donc j'ai converti cette logique en ayant une partie

Maintenant total_services est un alias virtuel pour la requête et contient le nombre distinct pour chaque hôtel, j'ai donc comparé ce nombre au nombre d'identifiants fournis dans IN() partie cela renverra les hôtels qui doivent contenir ces services

GROUP BY and HAVING Clause