Para su solución, puede utilizar COUNT(DISTINCT)
con HAVING
y GROUP BY
cláusulas
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();
}
En la consulta anterior, agregué una selección más para contar identificadores de servicio distintos para cada hotel, es decir,
Entonces también necesito un grupo para ese conteo, así que agregué
Ahora, aquí viene la parte complicada, ya que mencionó que necesita un hotel que tenga todos los ID de servicio como ID (1,2,3), por lo que los hoteles que contienen estos 3 servicios deben devolverse cuando los usamos en sus funciones u operaciones como where servid_id = 1 or servid_id = 2 servid_id = 3
que es exactamente lo que no quieres AND
operación que el hotel debe tener estos 3, así que convertí esta lógica teniendo parte
Ahora total_services
es un alias virtual para la consulta y contiene el recuento distinto de cada hotel, por lo que comparé este recuento con el recuento de identificadores proporcionados en IN()
parte esto devolverá los hoteles que deben contener estos servicios