我有一个数据库(我无法更改),一个表看起来像这样:
| ID:integer | fk:integer | next:[integer array] |
--------------------------------------------------
| 1 | 711 | {4} |
| 2 | 712 | {6} |
| 3 | 788 | |
| 4 | 799 | {7} |
--------------------------------------------------
现在我尝试定义一个Query作为第一行的数据ID = 1
和下一行,所有数据ID
都在整数数组next
中{{{ 1}})以便我的查询返回:
{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
然后对于Array中的每个元素,我以编程方式在循环中以SELECT * FROM tablenm WHERE ID = 1
运行相同的查询,但这看起来像一个脏黑客,我希望有一个SQL语句的解决方案。
答案 0 :(得分:2)
这不需要递归,只需要数组取消嵌套。
这应该有效:
select * from tablename where id=1
UNION ALL
select * from tablename where id
in (select unnest(next) from tablename where id=1);
答案 1 :(得分:2)
您可以在加入条件中使用= 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}'