Doctrine中DISTINCT语句失效,无法获取唯一酒店数据
解决Doctrine QueryBuilder获取唯一酒店数据的问题
你当前的写法踩了Doctrine QueryBuilder的一个小坑——distinct('hotel')并不是你想的那样针对单个字段去重,而是会尝试对整个查询结果集的hotel字段做去重,但因为你查询的是self(也就是SearchResult实体),结果里会包含SearchResult的所有字段,只要这些字段有差异,就会保留对应的行,所以才会返回所有关联的酒店数据。
下面分两种场景给你解决方案:
场景1:获取所有唯一的Hotel实体列表
如果你的目标是拿到该请求下所有不重复的Hotel实体,需要调整查询的select目标,直接选择hotel并配合distinct():
$qb = $this->createQueryBuilder('self'); $qb->select('hotel') ->distinct() ->join('self.hotel', 'hotel') ->where('self.request = :id') ->setParameter('id', $requestId); return $qb->getQuery()->getResult();
这段代码会生成类似这样的SQL:
SELECT DISTINCT hotel.* FROM search_result self JOIN hotel hotel ON self.hotel_id = hotel.id WHERE self.request_id = ?
最终返回的是去重后的Hotel实体集合。
场景2:统计唯一酒店的数量(匹配你期望的SQL)
如果你的需求是统计有多少个唯一的酒店,那就要用COUNT(DISTINCT ...)的写法:
$qb = $this->createQueryBuilder('self'); $qb->select('COUNT(DISTINCT hotel.id) as uniqueHotelCount') ->join('self.hotel', 'hotel') ->where('self.request = :id') ->setParameter('id', $requestId); return $qb->getQuery()->getSingleScalarResult();
这会生成和你期望几乎一致的SQL:
SELECT COUNT(DISTINCT hotel.id) AS uniqueHotelCount FROM search_result self JOIN hotel hotel ON self.hotel_id = hotel.id WHERE self.request_id = ?
调用getSingleScalarResult()会直接返回统计的数字,不用再处理结果集。
简单总结下:你之前的问题核心是查询的主体是SearchResult而不是Hotel,导致去重逻辑没有作用在酒店实体上,调整查询的目标或者改用统计函数就能解决啦。
内容的提问来源于stack exchange,提问作者randomUser
相关产品推荐
相关产品推荐

