Pro své řešení můžete použít COUNT(DISTINCT)
s HAVING
a 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();
}
Ve výše uvedeném dotazu jsem přidal ještě jeden výběr jako počítání odlišných ID služeb pro každý hotel, tj.
Pak také potřebuji skupinu pro tento počet, takže jsem přidal
Nyní přichází ta záludná část, jak jste zmínili, že potřebujete hotel, který má všechna ID služeb, jako jsou id (1,2,3), takže hotely, které obsahují tyto 3 služby, by měly být vráceny, když použijeme v jeho provedení nebo operaci jako where servid_id = 1 or servid_id = 2 servid_id = 3
což je přesně to, co nechcete AND
provoz, který hotel musí mít tyto 3, takže jsem tuto logiku převedl tím, že mám část
Nyní total_services
je virtuální alias pro dotaz a obsahuje odlišný počet pro každý hotel, takže jsem tento počet porovnal s počtem poskytnutých ID v IN()
část to vrátí hotely, které musí obsahovat tyto služby