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

如何用Django ORM编写PostgreSQL无聚合的GROUP BY主键查询

解决方案

在PostgreSQL中,主键能唯一确定表内其他字段的值,你要实现的GROUP BY id查询本质是对JOIN后产生的重复主键行去重。对应的Django ORM实现可直接使用**distinct()**方法,无需伪聚合或hack手段:

假设你的模型为MyTable,关联表用select_related/prefetch_related处理,过滤条件用filter:

MyTable.objects.select_related('关联模型')  # 对应SQL中的JOIN操作
               .filter(...)  # 对应WHERE条件
               .only('id', 'field1')  # 仅选择需要的字段,对应SELECT t.id, t.field1
               .distinct('id')  # 按id去重,等价于PostgreSQL的GROUP BY id

为什么这个方法可行?

  1. PostgreSQL支持DISTINCT ON (id)语法,Django的distinct('id')会自动生成该SQL,效果与GROUP BY id完全一致,且性能更优(无需分组聚合计算)。
  2. 由于id是主键,每个id对应的field1值唯一,去重后结果与原SQL完全匹配。

进阶替代方案(匹配原SQL结构)

如果需要严格对应原SQL的GROUP BY写法,可结合RawSQL实现,但不如distinct()简洁:

from django.db.models import RawSQL

MyTable.objects.select_related('关联模型')
               .filter(...)
               .annotate(_=RawSQL('GROUP BY id', ()))
               .values('id', 'field1')

更推荐第一种distinct('id')的方式,它符合Django ORM设计规范,代码简洁高效。

内容的提问来源于stack exchange,提问作者Lukasz Czerwinski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:15:30