是否可以进行递归SQL查询?

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,其中包含列idval.它被定义为两个选择合并的结果union all.

首先select得到root(where id = :selectedid).

其次select是迭代地跟随先前结果的子项,直到没有任何东西返回.

然后可以像普通表一样处理最终结果.在这种情况下,val列被求和.


Chr*_* KL 34

从版本8.4开始,PostgreSQL 使用SQL标准语法对公用表表达式进行递归查询支持WITH.


Por*_*man 15

如果您想要一个适用于任何ANSI SQL-92 RDBMS 的可移植解决方案,则需要在表中添加一个新列.

Joe Celko是嵌套集方法的原始作者,用于在SQL中存储层次结构.您可以通过Google "嵌套集"层次结构来了解有关背景的更多信息.

或者您可以将parentid重命名为leftid并添加rightid.

以下是我总结嵌套集的尝试,由于我不是Joe Celko,因此它很糟糕:SQL是一种基于集合的语言,而邻接模型(存储父ID)不是基于集合的层次结构表示.因此,没有基于集合的纯方法来查询邻接模式.

然而,近年来大多数主要平台都引入了扩展来处理这个精确的问题.因此,如果某人回复了Postgres特定的解决方案,请务必使用它.


小智 11

在PostgreSQL中有几种方法可以满足您的需求.

像这样的东西:

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)

看到这篇文章:


Dar*_*opp 5

使用公用表表达式.

可能只想表明这是SQL Server 2005或更高版本.戴尔拉根

这是一篇关于SqlTeam递归但没有公用表表达式的文章.


Fly*_*wat 5

如果您使用SQL Server 2005,使用公用表表达式有一种非常酷的方法.

它需要创建一个临时表所需的所有工作,并且基本上允许您只使用WITH和UNION来完成所有操作.

这是一个很好的教程:

http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1278207,00.html