Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Symfony2 - Doctrine2 QueryBuilder WHERE IN ManyToMany-Feld

Für Ihre Lösung können Sie COUNT(DISTINCT) verwenden mit HAVING und GROUP BY Klauseln

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();
}

In der obigen Abfrage habe ich eine weitere Auswahl hinzugefügt, um unterschiedliche Service-IDs für jedes Hotel zu zählen, dh

Dann brauche ich auch eine Gruppierung für diese Zählung, also habe ich

hinzugefügt

Jetzt kommt der knifflige Teil, wie Sie erwähnt haben, dass Sie Hotels benötigen, die alle Service-IDs wie IDs (1,2,3) haben, sodass Hotels, die diese 3 Dienste enthalten, zurückgegeben werden sollten, wenn wir sie in ihren Leistungen oder Operationen wie where servid_id = 1 or servid_id = 2 servid_id = 3 Das ist genau das, was Sie nicht mit dem AND wollen Operation, dass das Hotel diese 3 haben muss, also habe ich diese Logik konvertiert, indem ich Teil

hatte

Jetzt total_services ist ein virtueller Alias ​​für die Abfrage und enthält die eindeutige Anzahl für jedes Hotel, daher habe ich diese Anzahl mit der Anzahl der bereitgestellten IDs in IN() verglichen Ein Teil davon wird die Hotels zurückgeben, die diese Dienstleistungen enthalten müssen

GROUP BY and HAVING Clause