我有一张桌子,里面有类似的列
entityID, entityName, parentID
如何编写查询以返回实体的所有父级级别,以返回类似
childentityname, parentlevel1name, parentlevel2name, parentLevel3name and so on
无论如何,我都不是 SQL 忍者。这可能吗?如果是这样,怎么做?
我正在使用 Microsoft SQL Server 数据库。
我有一张桌子,里面有类似的列
entityID, entityName, parentID
如何编写查询以返回实体的所有父级级别,以返回类似
childentityname, parentlevel1name, parentlevel2name, parentLevel3name and so on
无论如何,我都不是 SQL 忍者。这可能吗?如果是这样,怎么做?
我正在使用 Microsoft SQL Server 数据库。
递归 CTE 是您需要在这里查看的(编辑:仅在 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
在 postgres 上,这正是WITH RECURSIVE
它的用途。您可能不需要做更多的事情,只需从(链接到这里)文档中更改列名。
我不知道 OP 的数据库是否支持递归,可能取决于版本号。如果可用,语法将相似或相同。如果没有,那就是大麻烦了。制作纯 SQL 解决方案非常困难,尤其是在级别数不受限制的情况下。
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 级,那么用户会收到一个错误,告诉他们他们不能将它设置得那么深。如果任何级别引用了顶级级别或之前的级别之一,那么还会生成一个错误,指示循环递归(如果允许持续存在,这将导致应用程序稍后崩溃)。
编辑:我缩短了名字。没有人想看到我为那个愚蠢的桌子命名的愚蠢荒谬的命名约定;)