我正在尝试建立一个深度递归自联接查询。桌子像这样:
Id | ParentId
1 | NULL
2 | 1
3 | 1
4 | 2
5 | 3
6 | 8
7 | 9
对于ID 1,我的查询应获取1,2,3,4,5,因为它们是1的子代或1的子代。在给定的示例中,查询中不应包含6和7结果。
我尝试使用CTE,但是却得到大量重复:
WITH CTE AS (
SELECT Id, ParentId
FROM dbo.Table
WHERE ParentId IS NULL
UNION ALL
SELECT t.Id, t.ParentId
FROM dbo.Table t
INNER JOIN CTE c ON t.ParentId = c.Id
)
SELECT * FROM CTE
想法?
答案 0 :(得分:1)
您可以尝试使用DISTINCT
来过滤重复的行。
;WITH CTE AS (
SELECT Id, ParentId
FROM T
WHERE ParentId IS NULL
UNION ALL
SELECT t.Id, t.ParentId
FROM T
INNER JOIN CTE c ON t.ParentId = c.Id
)
SELECT DISTINCT Id, ParentId
FROM CTE
答案 1 :(得分:0)
使用CTE
尝试以下查询,您可以在@parentID
处设置parentId:
DECLARE @parentID INT = 1
;WITH cte AS
(
SELECT
t.ID
, t.ParentId
FROM @table t
),
cteParent AS
(
SELECT
t.ID
, t.ParentId
FROM @table t
WHERE t.ParentId IN (SELECT t1.ID FROM @table t1 WHERE T1.ParentId = @parentID)
)
SELECT
DISTINCT c1.ID
, c1.ParentId
FROM cte c1
INNER JOIN cte c2 ON c2.ParentId = c1.ID
UNION ALL
SELECT *
FROM cteParent
以及示例数据:
DECLARE @table TABLE
(
ID INT
, ParentId INT
)
INSERT INTO @table
(
ID,
ParentId
)
VALUES
(1, NULL )
, (2, 1 )
, (3, 1 )
, (4, 2 )
, (5, 3 )
, (6, 8 )
, (7, 9 )
输出:
ID ParentId
1 NULL
2 1
3 1
4 2
5 3
答案 2 :(得分:0)
尝试使用此sql脚本生成父子层次结构
;WITH CTE(Id , ParentId)
AS
(
SELECT 1 , NULL UNION ALL
SELECT 2 , 1 UNION ALL
SELECT 3 , 1 UNION ALL
SELECT 4 , 2 UNION ALL
SELECT 5 , 3 UNION ALL
SELECT 6 , 8 UNION ALL
SELECT 7 , 9
)
,Cte2
AS
(
SELECT Id ,
ParentId ,
CAST('\'+ CAST(Id AS VARCHAR(MAX))AS VARCHAR(MAX)) AS [Hierarchy]
FROM CTE
WHERE ParentId IS NULL
UNION ALL
SELECT c1.Id ,
c1.ParentId ,
[Hierarchy]+'\'+ CAST(c1.Id AS VARCHAR(MAX)) AS [Hierarchy]
FROM Cte2 c2
INNER JOIN CTE c1
ON c1.ParentId = c2.Id
)
SELECT Id,
RIGHT([Hierarchy],LEN([Hierarchy])-1) AS ParentChildHierarchy
FROM Cte2
GO
结果
Id ParentChildHierarchy
-------------------------
1 1
2 1\2
3 1\3
5 1\3\5
4 1\2\4
答案 3 :(得分:0)
我没有看到重复的东西。
您的代码在您提供的数据上返回以下内容:
Id ParentId
1
2 1
3 1
5 3
4 2
这就是你想要的。
Here是db <>小提琴。
代码如下:
WITH t as (
SELECT *
FROM (VALUES (1, NULL), (2, 1), (3, 1), (4, 2), (5, 3), (6, 8), (7, 9)
) v(id, parentId)
),
CTE AS (
SELECT Id, ParentId
FROM t
WHERE ParentId IS NULL
UNION ALL
SELECT t.Id, t.ParentId
FROM t
INNER JOIN CTE c ON t.ParentId = c.Id
)
SELECT *
FROM CTE;
如果实际结果集中有重复项,则可能是原始表中有重复项。我建议在执行递归逻辑之前 删除它们:
with t as (
select distinct id, parentid
from <your query>
),
. . .
然后运行递归逻辑。
答案 4 :(得分:0)
此查询将为您提供帮助
CREATE TABLE #table( ID INT, ParentId INT )
INSERT INTO #table(ID,ParentId)
VALUES (1, NULL ), (2, 1 ), (3, 1 ), (4, 2 ), (5, 3 ), (6, 8 ), (7, 9 )
;WITH CTE AS (
SELECT ID FROM #table WHERE PARENTID IS NULL
UNION ALL
SELECT T.ID FROM #table T
INNER JOIN #table T1 ON T.PARENTID =T1.ID
) SELECT * FROM CTE