[英]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.