Đối với giải pháp của mình, bạn có thể sử dụng COUNT(DISTINCT)
với HAVING
và GROUP BY
mệnh đề
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();
}
Trong truy vấn trên, tôi đã thêm một lựa chọn nữa là đếm id dịch vụ riêng biệt cho từng khách sạn, tức là
Sau đó, tôi cũng cần một nhóm theo số lượng đó nên tôi đã thêm vào
Bây giờ đến phần khó khăn như bạn đã đề cập là bạn cần khách sạn có tất cả các id dịch vụ như id (1,2,3) để các khách sạn có chứa 3 dịch vụ này sẽ được trả lại khi chúng tôi sử dụng trong quá trình biểu diễn hoặc hoạt động của nó như where servid_id = 1 or servid_id = 2 servid_id = 3
chính xác là bạn không muốn AND
hoạt động mà khách sạn phải có 3 cái này vì vậy tôi đã chuyển đổi logic này bằng cách có một phần
Hiện tại total_services
là một bí danh ảo cho truy vấn và giữ số lượng riêng biệt cho từng khách sạn, vì vậy tôi đã so sánh số lượng này với số lượng id được cung cấp trong IN()
phần này sẽ trả về các khách sạn phải chứa các dịch vụ này