You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:34:17