如何用Django ORM实现等价于指定INNER JOIN的SQL查询?
Django ORM 实现等价INNER JOIN的查询
现有Employee表与Branch表,Branch表的mgr_id是关联Employee表emp_id的外键。对应的SQL内连接查询如下:
select blog_employee.emp_id, blog_employee.first_name, blog_branch.branch_name from blog_employee join blog_branch on blog_employee.emp_id = blog_branch.mgr_id ;
使用Branch.objects.select_related('mgr_id')会生成LEFT OUTER JOIN,无法得到预期结果,以下是两种实现等价INNER JOIN的方法:
方法1:从Branch模型过滤后关联查询
select_related默认使用LEFT JOIN,只需过滤掉mgr_id为空的Branch记录,即可等效为INNER JOIN:
# 假设Branch模型中外键字段名为mgr(Django外键默认存储字段为mgr_id) result = Branch.objects.filter(mgr__isnull=False).select_related('mgr').values( 'mgr__emp_id', 'mgr__first_name', 'branch_name' )
filter(mgr__isnull=False)确保只保留存在对应经理的分支select_related('mgr')关联关联的Employee记录,此时生成的SQL为INNER JOINvalues指定返回的字段,与原SQL输出一致
方法2:从Employee模型反向查询
如果Employee模型中定义了Branch外键的反向关联(比如Branch的外键mgr设置了related_name='branches'),可以直接从员工表出发查询关联分支:
# 假设Employee模型的反向关联名为branches result = Employee.objects.filter(branches__isnull=False).values( 'emp_id', 'first_name', 'branches__branch_name' )
这种方式生成的SQL天然是INNER JOIN,结果与原SQL完全匹配。
验证生成的SQL
可以通过打印查询集的query属性确认SQL是否符合预期:
print(result.query)
内容的提问来源于stack exchange,提问作者Ashwin Gohil
相关产品推荐
相关产品推荐

