如何用Django ORM编写基于固定值集合的子查询?
Django ORM实现固定值集合的子查询
要实现你需要的子查询,有两种可行的方式,具体如下:
方法一:纯ORM构造(无原生SQL)
利用Django的Union合并多个空QuerySet的注解结果,模拟固定值集合:
from django.db.models import OuterRef, Subquery, Value, CharField, IntegerField from my_app.models import Person # 定义固定值集合 fixed_age_data = [ {"name": "homer", "age": 35}, {"name": "marge", "age": 34}, ] # 构造单个固定值的QuerySet,再合并 combined_qs = None for item in fixed_age_data: single_qs = Person.objects.none().annotate( name=Value(item["name"], output_field=CharField()), age=Value(item["age"], output_field=IntegerField()) ) if combined_qs is None: combined_qs = single_qs else: combined_qs = combined_qs.union(single_qs) # 构造子查询,关联外部表的name字段 subquery = combined_qs.filter(name=OuterRef("name")).values("age")[:1] # 最终查询 Person.objects.annotate(new_age=Subquery(subquery))
方法二:使用RawSQL(更贴近原生SQL)
如果你的数据库支持VALUES语法(如PostgreSQL),可以直接用RawSQL构造子查询,更简洁:
from django.db.models import OuterRef, Subquery, RawSQL from my_app.models import Person # 构造子查询 subquery = RawSQL( "SELECT age FROM (VALUES (%s, %s), (%s, %s)) AS new_ages(name, age) WHERE new_ages.name = %s", ["homer", 35, "marge", 34, OuterRef("name")] ) # 最终查询 Person.objects.annotate(new_age=Subquery(subquery))
两种方法都能实现你需要的效果:匹配到name的记录返回对应age,未匹配到的返回NULL。
内容的提问来源于stack exchange,提问作者LondonRob
相关产品推荐
相关产品推荐

