看起來這應該是一個簡單解決方案的常見問題,但我還沒有找到它。 我想計算child_order
,這是不同的子表中的行出現的順序如在下面的數據顯示如下:爲前N個不同的子錶行選擇所有行
child_order PK1 PK2 ACCESS ACCESS_ID
1 99 Al NULL NULL
2 55 Charles Accounts 1
2 55 Charles Desktop 2
2 55 Charles Printer 3
2 55 Charles Servers 4
2 55 Charles VMs 5
3 66 Charles Desktop 2
3 66 Charles VMs 5
4 22 Chris Desktop 2
4 22 Chris Printer 3
4 22 Chris Servers 4
5 89 Evan Desktop 2
由查詢像檢索:
SELECT sub1.*
FROM (
SELECT ??? as child_order, sub2.*
FROM (
SELECT ct.PK1, ct.PK2, pt1.ACCESS, pt1.ACCESS_ID
FROM child_table ct
LEFT JOIN some_linktable lt ON lt.child_id = ct.id
LEFT JOIN parent_table1 pt1 ON lt.parent_id = pt1.id
WHERE ct.PK2 IN ('Charles', 'Evan', 'Al', 'Chris')
ORDER BY ct.PK2, pt1.ACCESS -- Order must be preserved
) sub2
) sub1
WHERE child_order < 10 AND (other_conditions)
我可以使用子查詢,聚合,分析等,但不是真正的CTE /「WITH」語句或臨時表,因爲動態生成SQL的複雜性。
具體來說,我爲連接多個表的查詢的搜索結果生成分頁SQL(針對多個DBMS)。 我想弄清楚如何簡單地顯示前N行,不包括由於連接而引起的重複(例如,Chris只計爲一行,Access
顯示「桌面,打印機,服務器」)。
我試過DENSE_RANK() OVER (ORDER BY PK1, PK2)
,但我當然得到PK1 PK2順序的排名,這對WHERE子句沒用。例如,Al的值會高於1.
我試過DENSE_RANK() OVER (ORDER BY PK2, ACCESS)
,但它僅枚舉搜索項,而不是子錶行。
我試過DENSE_RANK() OVER (PARTITION BY PK2, ACCESS ORDER BY (SELECT NULL))
(要得到DENSE_RANK使用它給出的行順序,這是我想如何排序值),但只返回「1」。
我會省略我的其他「嘗試隨機的東西」階段的嘗試。
我想避免有一個SELECT DISTINCT PK1, PK2 WHERE (search) ORDER BY (sortorder)
子查詢,因爲可能有零或非常多的主鍵字段,所以動態SQL生成會很棘手,另外,我懷疑性能會吸引所有WHERE sub3.field1 = sub2.field1 AND sub3.field2 = sub2.field2...
檢查。
我很感謝答案,但是這不會滿足要求,因爲不保留正確的順序。 內部查詢僅按子表進行排序,但沒有針對父表進行排序,相應的「前N行」將丟失。 一個可以作爲一個子查詢執行整個過濾,加入,排序的主查詢,然後再次執行它,以反對自身的行順序,但這似乎令人難以置信的複雜,我認爲將是一個非常常見的SQL問題:搜索,排序和來自加入的結果分頁。這看起來不合理嗎? –