Django 使用 Coalesce 从同一模型中获取最大长度值
Django get max length value from same model with Coalesce
我正在尝试使用 ORM 编写以下原始查询。我不确定是否可能。
select first_name,
middle_name,
COALESCE(middle_name, (
select middle_name
from contacts c2
where c2.first_name = c1.first_name
and c2.last_name = c1.last_name
and c2.middle_name is not null
order by length(c2.middle_name) desc
limit 1
)
) expected,
last_name
from contacts c1
预期结果如下,如果middle_name为null,从另一条具有相同first_name和last_name的记录中获取中间名。
id| first_name | middle_name | expected | last_name
1 | ahmet | <NULL> | burak | ozyurt
2 | ahmet | burak | burak | ozyurt
class Contact(models.Model):
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250, null=True, blank=True)
middle_name = models.CharField(max_length=250, null=True, blank=True)
数据库:Postgres
Django 版本:3.12
通过使用django ORM,您可以使用以下代码执行相同的查询
from django.db import models
from django.db.models.functions import Coalesce, Length
matched_middle_name_queryset = Contact.objects.filter(
first_name=models.OuterRef("first_name"),
last_name=models.OuterRef("last_name"),
middle_name__isnull=False,
).annotate(
middle_name_len=Length("middle_name")
).order_by("-middle_name_len").values("middle_name")[:1]
result = Contact.objects.annotate(
matched_middle_name=models.Subquery(matched_middle_name_queryset)
expected=Coalesce(
models.F("middle_name")
models.F("matched_middle_name"),
).values("id", "first_name", "middle_name", "expected", "last_name")
)
解释
models.OuterRef
用于从子查询的父查询中引用字段。
-
前缀在order_by("-middle_name_len")
是降序
.values("middle_name")
仅用于选择 middle_name
个值。
- 切片
[:1]
是为了限制子查询的结果为一个
小贴士
- 您可以使用
result.query
检查 ORM 将为您生成什么查询。
我正在尝试使用 ORM 编写以下原始查询。我不确定是否可能。
select first_name,
middle_name,
COALESCE(middle_name, (
select middle_name
from contacts c2
where c2.first_name = c1.first_name
and c2.last_name = c1.last_name
and c2.middle_name is not null
order by length(c2.middle_name) desc
limit 1
)
) expected,
last_name
from contacts c1
预期结果如下,如果middle_name为null,从另一条具有相同first_name和last_name的记录中获取中间名。
id| first_name | middle_name | expected | last_name
1 | ahmet | <NULL> | burak | ozyurt
2 | ahmet | burak | burak | ozyurt
class Contact(models.Model):
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250, null=True, blank=True)
middle_name = models.CharField(max_length=250, null=True, blank=True)
数据库:Postgres
Django 版本:3.12
通过使用django ORM,您可以使用以下代码执行相同的查询
from django.db import models
from django.db.models.functions import Coalesce, Length
matched_middle_name_queryset = Contact.objects.filter(
first_name=models.OuterRef("first_name"),
last_name=models.OuterRef("last_name"),
middle_name__isnull=False,
).annotate(
middle_name_len=Length("middle_name")
).order_by("-middle_name_len").values("middle_name")[:1]
result = Contact.objects.annotate(
matched_middle_name=models.Subquery(matched_middle_name_queryset)
expected=Coalesce(
models.F("middle_name")
models.F("matched_middle_name"),
).values("id", "first_name", "middle_name", "expected", "last_name")
)
解释
models.OuterRef
用于从子查询的父查询中引用字段。-
前缀在order_by("-middle_name_len")
是降序.values("middle_name")
仅用于选择middle_name
个值。- 切片
[:1]
是为了限制子查询的结果为一个
小贴士
- 您可以使用
result.query
检查 ORM 将为您生成什么查询。