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

Django ORM在MySQL/MariaDB中按指定列分组的实现方法咨询

在Django ORM中实现无聚合的指定列分组(无需RawSQL)

不需要编写RawSQL,Django ORM提供了几种适配主流数据库(包括MySQL/MariaDB)的方案:

方法1:values() + distinct() 指定字段去重

普通distinct()会对全列去重,但结合values()限定需要分组的字段后,只会对指定字段组合去重,本质就是按指定列分组取唯一值,性能更优:

# 按id、username分组去重,返回字典格式结果
User.objects.filter(groups__name='foo').values('id', 'username').distinct()

方法2:annotate() 配合无意义聚合(获取完整模型实例)

如果需要返回完整的User模型实例而非字典,可以先通过annotate()添加一个不影响结果的聚合字段,再结合values()和distinct()筛选分组后的主键,最后通过主键查询获取实例:

from django.db.models import Count

# 先获取分组后的主键集合
grouped_user_ids = User.objects.filter(groups__name='foo').annotate(
    dummy_count=Count('id')
).values('id').distinct()

# 通过主键查询获取完整模型实例
unique_users = User.objects.filter(id__in=[item['id'] for item in grouped_user_ids])

方法3:子查询过滤(复杂关联场景)

针对多表关联的复杂分组需求,用子查询先筛选出符合条件的唯一主键,再外层查询获取实例:

from django.db.models import Subquery, OuterRef

# 子查询获取符合条件的唯一user id
subquery = User.objects.filter(
    id=OuterRef('id'), groups__name='foo'
).values('id').distinct()

unique_users = User.objects.filter(id__in=Subquery(subquery))

优先级建议

优先使用values()+distinct()的组合,写法简洁且性能最优,适配所有主流数据库。

内容的提问来源于stack exchange,提问作者Rémi Desgrange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:57:44