繁体   English   中英

Postgres:使用数组的“递归”查询

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM