Ada*_*rce 62 sql postgresql recursive-query
我有一个类似于这样的表:
CREATE TABLE example (
id integer primary key,
name char(200),
parentid integer,
value integer);
Run Code Online (Sandbox Code Playgroud)
我可以使用parentid字段将数据排列到树结构中.
现在这是我无法解决的问题.给定一个parentid,是否可以编写一个SQL语句来添加该parentid下的所有值字段并递归树的分支?
更新:我正在使用posgreSQL,因此我无法使用奇特的MS-SQL功能.无论如何,我希望将其视为一般SQL问题.
顺便说一下,在提出问题的15分钟内得到6个答案给我留下了非常深刻的印象!去堆栈溢出!
End*_*ono 42
以下是使用公用表表达式的示例脚本:
with recursive sumthis(id, val) as (
select id, value
from example
where id = :selectedid
union all
select C.id, C.value
from sumthis P
inner join example C on P.id = C.parentid
)
select sum(val) from sumthis
Run Code Online (Sandbox Code Playgroud)
上面的脚本创建了一个名为"virtual"的表sumthis,其中包含列id和val.它被定义为两个选择合并的结果union all.
首先select得到root(where id = :selectedid).
其次select是迭代地跟随先前结果的子项,直到没有任何东西返回.
然后可以像普通表一样处理最终结果.在这种情况下,val列被求和.
Por*_*man 15
如果您想要一个适用于任何ANSI SQL-92 RDBMS 的可移植解决方案,则需要在表中添加一个新列.
Joe Celko是嵌套集方法的原始作者,用于在SQL中存储层次结构.您可以通过Google "嵌套集"层次结构来了解有关背景的更多信息.
或者您可以将parentid重命名为leftid并添加rightid.
以下是我总结嵌套集的尝试,由于我不是Joe Celko,因此它很糟糕:SQL是一种基于集合的语言,而邻接模型(存储父ID)不是基于集合的层次结构表示.因此,没有基于集合的纯方法来查询邻接模式.
然而,近年来大多数主要平台都引入了扩展来处理这个精确的问题.因此,如果某人回复了Postgres特定的解决方案,请务必使用它.
小智 11
在PostgreSQL中有几种方法可以满足您的需求.
如果您可以安装模块,请查看tablefunc contrib.它有一个connectby()函数来处理遍历树.http://www.postgresql.org/docs/8.3/interactive/tablefunc.html
另请查看ltree contrib,您可以调整您的表格使用:http://www.postgresql.org/docs/8.3/interactive/ltree.html
或者您可以使用PL/PGSQL函数自行遍历树.
像这样的东西:
create or replace function example_subtree (integer)
returns setof example as
'declare results record;
child record;
begin
select into results * from example where parent_id = $1;
if found then
return next results;
for child in select id from example
where parent_id = $1
loop
for temp in select * from example_subtree(child.id)
loop
return next temp;
end loop;
end loop;
end if;
return null;
end;' language 'plpgsql';
select sum(value) as value_sum
from example_subtree(1234);
Run Code Online (Sandbox Code Playgroud)
Qua*_*noi 10
进行递归查询的标准方法SQL是递归的CTE.PostgreSQL支持他们,因为8.4.
在早期版本中,您可以编写递归集返回函数:
CREATE FUNCTION fn_hierarchy (parent INT)
RETURNS SETOF example
AS
$$
SELECT example
FROM example
WHERE id = $1
UNION ALL
SELECT fn_hierarchy(id)
FROM example
WHERE parentid = $1
$$
LANGUAGE 'sql';
SELECT *
FROM fn_hierarchy(1)
Run Code Online (Sandbox Code Playgroud)
看到这篇文章:
如果您使用SQL Server 2005,使用公用表表达式有一种非常酷的方法.
它需要创建一个临时表所需的所有工作,并且基本上允许您只使用WITH和UNION来完成所有操作.
这是一个很好的教程:
http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1278207,00.html