För din lösning kan du använda COUNT(DISTINCT)
med HAVING
och GROUP BY
klausuler
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();
}
I ovanstående fråga har jag lagt till ytterligare ett urval som räknar distinkta tjänste-ID för varje hotell, dvs.
Sedan behöver jag också en grupp för den räkningen så jag lade till
Nu kommer här den knepiga delen som du nämnde att du behöver hotell som har alla tjänste-id som id (1,2,3) så hotell som innehåller dessa 3 tjänster ska returneras när vi använder i dess utför eller operation som where servid_id = 1 or servid_id = 2 servid_id = 3
vilket är exakt du inte vill ha AND
operation att hotellet måste ha dessa 3 så jag konverterade denna logik genom att ha del
Nu total_services
är ett virtuellt alias för frågan och innehåller det distinkta antalet för varje hotell så jag har jämfört detta antal med antalet angivna ID i IN()
del detta kommer att returnera hotellen som måste innehålla dessa tjänster