我有一个表格,其中的列如下:
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
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级,则会向用户发送错误消息,告诉他们不能设置得那么深。如果任何一级引用顶级或先前的某个级别,则还会生成错误,指示循环递归(如果允许持续存在,将在后面崩溃应用程序)。
编辑:我缩短了名称。没有人想看到我愚蠢荒谬的命名约定;)
在Postgres上,这正是WITH RECURSIVE
的用途。您可能只需要从(此处链接)文档中更改列名称。
我不知道OP的数据库是否支持递归,可能取决于版本号。如果可用,则语法将类似或相同。如果没有,则会很麻烦。要想做出纯SQL解决方案尤其困难,特别是如果级别数量是无限的。