請參閱過濾問題描述、示例資料和 postgres 查詢的唯一值。我想將 SQL 轉換為查詢集。我覺得我很接近但不完全。
SELECT Column_A, Column_B, Column_C, 0 as RN
FROM TABLE
WHERE COLUMN_C is null and Column_B in (UserA, UserB, UserC)
UNION ALL
SELECT Column_A, Column_B, Column_C, RN
FROM (
SELECT A.*, ROW_NUMBER() over (partition by A.column_C Order by case A.column_B when 'UserA' then 0 else 1 end, U.Time_Created) rn
FROM Table A
INNER JOIN user U
on U.Column_B = A.Column_B
WHERE A.Column_C is not null and ColumnB in (userA, userB, UserC)) B
WHERE RN = 1
這是我到目前為止:
qs1 = Table.objects.filter(Column_C__isnull=True).annotate(rn=Value(0))
qs2 = Table.objects.annotate(rn=Window(
expression=RowNumber(),
partition_by=[Column_C],
order_by=[Case(When(Column_B=UserA, then=0), default=1), 'Table_for_Column_B__time_created']
)).filter(Column_C__isnull=False, rn=1)
return qs2.union(qs1)
這不太行。
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.
接下來,我嘗試在子查詢中提取中間結果,以允許在外部查詢中進行過濾,因為我只需要行號 = 1 的行。
qs1 = Table.objects.filter(Column_C__isnull=True).annotate(rn=Value(0))
qs2 = Table.objects.annotate(rn=Window(
expression=RowNumber(),
partition_by=[Column_C],
order_by=[Case(When(Column_B=UserA, then=0), default=1), 'Table_for_Column_B__time_created']
)).filter(pk=OuterRef('pk'))
qs3 = Table.objects.annotate(rn=Subquery(qs2.values('rn'))).filter(Column_C__isnull=False, rn=1)
return qs3.union(q1)
這次沒有例外,但這不起作用。表中的每一行都有 row_number=1 注釋。在原始示例中,查詢集回傳所有 7 行,而不是過濾到 5 行。
- 是否可以過濾視窗運算式?
- 將視窗查詢轉換為子查詢時要記住的最佳實踐是什么?
- 有沒有更好的方法來構造查詢集?
uj5u.com熱心網友回復:
您應該可以在沒有視窗運算式的情況下使用SubQuery執行此操作
首先為按Column_B=UserA匹配排序的子查詢創建一個查詢集,然后time_created
from django.db.models import Case, When, Q, Subquery, OuterRef
tables_ordered = Table.objects.filter(
Column_C=OuterRef('Column_C')
).annotate(
user_match=Case(When(Column_B=UserA, then=0), default=1)
).order_by('user_match', 'time_created')
那么這個子查詢回傳的匹配的第一個PKColumn_C從OuterRef,類似于從你的窗函式選擇第一行
first_pk_for_each_column_c = Subquery(tables_ordered.values('pk')[:1])
然后使用兩個Q物件創建一個OR,如果Column_C為 NULL 或pk匹配pk子查詢中的第一個,則選擇該行
Table.objects.filter(
Q(Column_C__isnull=True) | Q(pk=first_pk_for_each_column_c)
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/361127.html
標籤:姜戈 django-queryset django-postgresql
下一篇:如何在django物件中注釋字串
