我在 Django 中有两个模型,A
and B
.
Each A
有几个B
s 分配给它,并且B
s 是有序的,这是通过字段完成的B.order_index
对于任何从零开始向上计数A
.
我想编写一个查询来检查是否有A
其中一些B
s 有间隙或有重复order_index
values.
在 SQL 中,可以这样完成:
SELECT order_index, RANK() OVER(PARTITION BY a_id ORDER BY order_index ASC) - 1 AS rnk
WHERE rnk = order_index'
但是,当我在 Django 中使用以下代码尝试此操作时:
B.objects.annotate(rank=RawSQL("RANK() OVER(PARTITION BY a_id ORDER BY order_index ASC) - 1", [])).filter(rank=F('order_index'))
我收到一条错误消息:
django.db.utils.ProgrammingError: window functions are not allowed in WHERE
LINE 1: ...- 1) AS "rank" FROM "main_b" WHERE (RANK() OVE...
在 SQL 中,通过将整个内容包装在子查询中并将Where子句应用于该子查询,可以很容易地解决这个问题。我怎样才能在 Django 中做同样的事情?
表达此类查询的一种可能的解决方法是使用https://github.com/dimagi/django-cte.
from django_cte import With
cte = With(
B.objects.all().annotate(
rank=Window(
expression=Rank(),
partition_by=F('a_id'),
order_by=F('order_index').asc()
)
)
)
cte.join(B.objects.all(), id=cte.col.id).with_cte(cte).annotate(
rank=cte.col.rank
).filter(
rank=F('order_index')
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)