1

我有一个数据库(我无法更改),其中一个表如下所示:

| 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}                  |
--------------------------------------------------

但随后停止,因此它只会产生具有指定元素IDnext元素。

我试过了。像这样,但我无法让它工作:

SELECT * FROM tablenm WHERE ID = ANY(SELECT next FROM tablenm WHERE ID = 1) AND ID = 1

我使用的当前解决方法是首先使用此查询:

SELECT * FROM tablenm WHERE ID = 1

然后对于 Array 中的每个元素,我以ID编程方式在循环中使用 s 运行相同的查询,但这看起来像一个肮脏的 hack,我希望有一个使用 1 个 SQL 语句的解决方案。

4

2 回答 2

2

这不需要递归,只需数组取消嵌套。

这应该有效:

select * from tablename where id=1
UNION ALL
select * from tablename where id
  in (select unnest(next) from tablename where id=1);
于 2013-09-30T19:30:16.137 回答
2

您可以= ANY(array)在 JOIN 条件中使用:

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}'
于 2013-09-30T22:42:17.137 回答