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