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

Django使用INNER JOIN时原始查询与ORM查询结果重复如何解决?

问题原因
  • 原生SQL查询逻辑问题:你通过Projekt.objects.raw()执行的关联查询,拼接了一对多关系的项目表和用户资料表,INNER JOIN 会为每一组「项目+关联用户」生成一条独立记录,因此一个项目关联多少个用户,就会返回多少条重复的项目数据,和你预期的单条项目记录不符。同时你的SQL字段包含了用户维度的属性,返回结果本身就是用户粒度的,自然条数等于项目下的用户数量。
  • ORM查询逻辑错误:你编写的Profile.objects.filter(projekt=profile.projekt)本质是查询指定项目下的所有用户资料,返回结果条数天然等于该项目的用户数,和你要查询项目对象的需求不匹配。
解决方法

分不同需求场景给出方案:

场景1:仅需获取当前用户所属的单个项目信息

直接通过外键关联取值即可,无需额外过滤查询:

profile = Profile.objects.get(user=request.user)
# 直接取Profile关联的Projekt外键对象即可,不会产生重复
projekt = profile.projekt

场景2:需要获取项目列表,同时关联查询每个项目下的用户数据

使用Django ORM的prefetch_related预加载关联的用户资料,不会产生JOIN导致的重复记录:

# 预加载每个项目关联的所有Profile数据
projekt_list = Projekt.objects.all().prefetch_related('profile_set')

# 遍历项目不会重复,单个项目下可单独取关联用户
for projekt in projekt_list:
    print(f"项目名:{projekt.projekt}")
    # 该项目下的所有用户资料
    for profile in projekt.profile_set.all():
        print(f"关联用户:{profile.user.last_name} {profile.user.first_name}")

场景3:必须使用原生SQL查询,需要对结果去重

PostgreSQL环境可使用DISTINCT ON按项目ID去重:

SELECT DISTINCT ON (stressz_projekt.id) projekt_id, stressz_projekt.projekt, last_name, first_name, stressz_profile.id, stressz_profile.user_id, auth_user.id 
FROM stressz_profile 
INNER JOIN stressz_projekt ON stressz_projekt.id = stressz_profile.projekt_id 
INNER JOIN auth_user ON auth_user.id = stressz_profile.user_id

MySQL环境可使用GROUP BY按项目维度聚合:

SELECT projekt_id, stressz_projekt.projekt 
FROM stressz_profile 
INNER JOIN stressz_projekt ON stressz_projekt.id = stressz_profile.projekt_id 
INNER JOIN auth_user ON auth_user.id = stressz_profile.user_id
GROUP BY stressz_projekt.id, stressz_projekt.projekt

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:24:03