[英]Postgres: “Recursive” query with Array
我有一個數據庫(無法更改),一個表如下所示:
| ID:integer | fk:integer | next:[integer array] |
--------------------------------------------------
| 1 | 711 | {4} |
| 2 | 712 | {6} |
| 3 | 788 | |
| 4 | 799 | {7} |
--------------------------------------------------
現在我嘗試定義一個查詢,作為第一行與數據ID = 1
個作為下一個行,與所有的數據ID
是整數數組中next
( {4}
使得我的查詢返回:
| ID:integer | fk:integer | next:[integer array] |
--------------------------------------------------
| 1 | 711 | {4} |
| 4 | 799 | {7} |
--------------------------------------------------
但是隨后停止,因此它只會生成具有指定ID
的元素及其next
元素。
我嘗試過…… 像這樣,但我無法使它工作:
SELECT * FROM tablenm WHERE ID = ANY(SELECT next FROM tablenm WHERE ID = 1) AND ID = 1
我當前使用的解決方法是首先使用此查詢:
SELECT * FROM tablenm WHERE ID = 1
然后,對於數組中的每個元素,我都以編程方式在循環中運行ID
s的相同查詢,但這看起來像是一堆骯臟的東西,我希望有1條SQL語句可以解決此問題。
這不需要遞歸,只需取消數組嵌套即可。
這應該工作:
select * from tablename where id=1
UNION ALL
select * from tablename where id
in (select unnest(next) from tablename where id=1);
您可以在JOIN條件中使用= ANY(array)
:
SELECT t2.*
FROM tbl t1
JOIN tbl t2 ON t2.id = ANY(t1.next)
OR t2.id = t1.id -- add first row
WHERE t1.id = 1 -- enter id to filter on once
ORDER BY (t2.id <> t1.id); -- "first row the data with ID = ?"
應該最快。
作為@Daniel解釋說, 這種形式(如您的查詢)包括只有一次的第一行。
如果要“更簡短的查詢”:
SELECT t2.*
FROM tbl t1
JOIN tbl t2 ON t2.id = ANY(t1.next || t1.id) -- append id to array
WHERE t1.id = 1; -- not sure if you need ORDER BY
比第一種形式更短但不快,因為它將在內部擴展為第一種形式的等效形式。 用EXPLAIN ANALYZE
測試性能。
應該注意, next
甚至可以為NULL
,因為:
SELECT NULL::int[] || 5 --> '{5}'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.