在 Django 模型查询中按顺序排列的原始 SQL
Posted
技术标签:
【中文标题】在 Django 模型查询中按顺序排列的原始 SQL【英文标题】:Raw SQL in order by in django model query 【发布时间】:2021-10-01 20:22:54 【问题描述】:我有一个这样的简单查询(我希望先出现 1 BHK,然后是 2BHK,然后是其他任何东西)
select *
from service_options
order by case space when '1BHK' then 0 when '2BHK' then 1 else 2 end,
space
在 Django 中,怎么做?我有一个模型名为ServiceOption
我试过了,但没有运气。
ServiceOption.objects.order_by(RawSQL("case space when '1BHK' then 0 when '2BHK' then 1 else 2 end,space"), ()).all()
我不想使用类似的东西执行原始查询
ServiceOption.objects.raw("raw query here")
在 Laravel 中,这样的事情可以很容易地像这样实现
Model::query()->orderByRaw('raw order by query here')->get();
我们将不胜感激。提前谢谢你。
【问题讨论】:
【参考方案1】:您可以使用.annotate(…)
[Django-doc],然后使用.order_by(…)
[Django-doc]:
from django.db.models import Case, IntegerField, Value, When
ServiceOption.objects.annotate(
sp=Case(
When(space='1BHK', then=Value(0)),
When(space='2BHK', then=Value(1)),
default=Value(2),
output_field=IntegerField()
)
).order_by('sp', 'space')
原始查询会到这里
SELECT *, CASE WHEN "service_options"."space" = 1BHK THEN 0 WHEN "service_options"."space" = 2BHK THEN 1 ELSE 2 END AS "sp" FROM "service_options" ORDER BY "sp" ASC, "service_options"."space" ASC
由于django-3.2,您可以使用.alias(…)
[Django-doc] 来防止将其计算为列和ORDER BY
子句:
from django.db.models import Case, IntegerField, Value, When
ServiceOption.objects.alias(
sp=Case(
When(space='1BHK', then=Value(0)),
When(space='2BHK', then=Value(1)),
default=Value(2),
output_field=IntegerField()
)
).order_by('sp', 'space')
原始查询会到这里
SELECT * FROM "service_options" ORDER BY CASE WHEN ("service_options"."space" = 1BHK) THEN 0 WHEN ("service_options"."space" = 2BHK) THEN 1 ELSE 2 END ASC, "service_options"."space" ASC
【讨论】:
您好,感谢您的解决方案。但是,有没有办法只为 order by 执行原始查询?在 laravel 中,我可以使用 $query->orderByRaw('raw order by query here') 之类的方法轻松完成。 为您的答案执行的实际查询将转换为select *, case space when '1BHK' then 0 when '2BHK' then 1 else 2 end as sp from service_options order by sp, space
但是,这与我在问题中建议的原始查询完全不同。
@KoushikDas: 不,如果您使用.annotate
执行此操作,那么它将在SELECT
和ORDER BY
子句中使用sp
,如果您使用.alias(...)
它只会在必要的地方使用ORDER BY
中的CASE ...
。以上是关于在 Django 模型查询中按顺序排列的原始 SQL的主要内容,如果未能解决你的问题,请参考以下文章