CakePHP 3.5.13中调用distinct()对生成的查询无效果的问题
为什么CakePHP 3.5.13中调用
distinct(['id'])没生成DISTINCT SQL? 这个问题其实是CakePHP ORM的自动优化机制在起作用,原因很直白:你当前的查询只选择了id字段,而id作为表的主键(默认场景下)本身就具备唯一性约束,加不加DISTINCT对查询结果没有任何实际影响,所以ORM自动帮你省略了这个多余的SQL关键字。
验证逻辑的小测试
如果你的查询选择多个字段,比如同时查询id和name,这时候distinct()就会生效:
$query = $Substances->find()->select(['id', 'name'])->distinct(['id']); debug($query->sql());
生成的SQL会包含DISTINCT,因为此时id+name的组合可能存在重复,DISTINCT能起到实际的去重作用。
强制生成DISTINCT(即使看起来冗余)
如果你确实需要在仅查询主键的场景下强制生成DISTINCT,可以用两种方式实现:
- 禁用自动字段优化,告诉ORM不要自作主张:
$query = $Substances->find() ->select(['id']) ->enableAutoFields(false) ->distinct(['id']);
- 直接传递
true给distinct()方法,不指定具体字段:
$query = $Substances->find() ->select(['id']) ->distinct(true);
两种方式生成的SQL都会变成:
SELECT DISTINCT Substances.id AS `Substances__id` FROM substances Substances
补充说明
官方文档里的distinct()示例通常针对多字段查询场景,这时候去重才有实际意义。当查询仅包含带唯一约束的字段(比如主键)时,ORM的优化逻辑会自动移除无意义的DISTINCT,这是合理的设计,避免生成冗余的SQL语句。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

