Dla swojego rozwiązania możesz użyć COUNT(DISTINCT)
z HAVING
i GROUP BY
klauzule
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();
}
W powyższym zapytaniu dodałem jeszcze jeden select jako zliczający różne identyfikatory usług dla każdego hotelu, tj.
Następnie potrzebuję również grupy dla tej liczby, więc dodałem
Teraz nadchodzi trudna część, jak wspomniałeś, że potrzebujesz hotelu, który ma wszystkie identyfikatory usług, takie jak identyfikatory (1,2,3), więc hotele, które zawierają te 3 usługi, powinny zostać zwrócone, gdy użyjemy ich w jego wykonaniu lub działaniu, takim jak where servid_id = 1 or servid_id = 2 servid_id = 3
czyli dokładnie nie chcesz AND
operacja, że hotel musi mieć te 3, więc przekonwertowałem tę logikę, mając część
Teraz total_services
jest wirtualnym aliasem zapytania i zawiera odrębną liczbę dla każdego hotelu, więc porównałem tę liczbę z liczbą dostarczonych identyfikatorów w IN()
część zwróci hotele, które muszą zawierać te usługi