sql >> Base de Datos >  >> RDS >> Mysql

Symfony2 - Doctrine2 QueryBuilder DÓNDE EN el campo ManyToMany

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

GROUP BY and HAVING Clause