如何在循环参考表中将所有父母的父母作为子对象的列?

时间:2011-06-15 21:19:55

标签: sql circular-reference

我有一个包含

列的表格
entityID, entityName, parentID

如何编写查询以返回实体的所有父级别,以返回类似

的内容
childentityname, parentlevel1name, parentlevel2name, parentLevel3name and so on

无论如何,我不是SQL忍者。这可能吗?如果是这样,怎么样?

我正在使用Microsoft SQL Server DB。

3 个答案:

答案 0 :(得分:3)

递归CTE是您需要的look here(编辑:仅在SQL SERVER 2005 +中)

有些事情:

WITH recurse_cte (entityID,entityName, parentID, Level)
AS
(
-- Anchor member definition
    SELECT e.entityID,e.entityName, e.parentID,
        0 AS Level
    FROM self_joined AS e
        UNION ALL
-- Recursive member definition
    SELECT e.entityID,e.entityName, e.parentID,
        Level + 1
     FROM self_joined AS e
    INNER JOIN recurse_cte AS cte
        ON e.entityID = cte.parentID
)

select * from recurse_cte

答案 1 :(得分:0)

关于postgres,这正是WITH RECURSIVE的用途。您可能不需要做更多的事情,只需更改(linked here)文档中的列名。

我不知道OP的DB是否支持递归,可能取决于版本号。如果可用,语法将类似或相同。如果没有,这是一个很大的麻烦。制作纯SQL解决方案非常困难,尤其是在级别数量无限制的情况下。

答案 2 :(得分:0)

SELECT 
  'accounts'.'id' AS id_0,
  'accounts'.'child_id' AS child_id_0, 
  'child_accounts_1'.'id' AS id_1, 
  'child_accounts_1'.'child_id' AS child_id_1, 
  'child_accounts_2'.'id' AS id_2, 
  'child_accounts_2'.'child_id' AS child_id_2, 
  'child_accounts_3'.'id' AS id_3, 
  'child_accounts_3'.'child_id' AS child_id_3, 
  'child_accounts_4'.'id' AS id_4, 
  'child_accounts_4'.'child_id' AS child_id_4
FROM 
  'accounts' 
LEFT OUTER JOIN 'accounts' 'child_accounts_1'
  ON 'child_accounts_1'.'id' = 'accounts'.'child_id'
LEFT OUTER JOIN 'accounts' 'child_accounts_2'
  ON 'child_accounts_2'.'id' = 'child_accounts_1'.'child_id'
LEFT OUTER JOIN 'accounts' 'child_accounts_3'
  ON 'child_accounts_3'.'id' = 'child_accounts_2'.'child_id'
LEFT OUTER JOIN 'accounts' 'child_accounts_4'
  ON 'child_accounts_4'.'id' = 'child_accounts_3'.'child_id'
WHERE 'accounts'.'id' = 56

这与你正在做的非常相似,只是我的是一个孩子的等级。

accounts表有一个引用自身的属性negative_overflow_account_id。这里将抓取嵌套的前5层的'id'和'negative_overflow_id'。

我在我的代码中写了一个循环,它将根据常量MAX_OVERFLOW生成此查询,当设置为'5'时将生成此查询,如果使用不同的数字,则会更多/更少。

基本上我的用例是确保有人没有设置无限循环,所以如果它达到5级,那么用户会告诉他们无法将其设置得那么深。如果任何级别引用顶级或前一级别之一,则还会生成一个错误,指示循环递归(如果允许持久化,则会在以后崩溃该应用程序)。

编辑:我缩短了名字。没有人想看到我那个愚蠢的桌子的愚蠢荒谬的命名惯例;)