我的表格中有以下数据
ID NAME PARENTID STATUS
----------- ------------------------------ ----------- ------
1 Folder A 0 0
2 Folder B 1 0
3 Folder C 2 1
4 Folder D 1 0
5 Folder E 4 0
6 Folder G 5 0
7 Folder H 6 1
以上记录来自表格[@Temp]。
[Name] - Folder Name
[ID] - Unique ID of folder in database (identity)
[ParentID] - Represents the parent of current folder.
查询以填充表格中的上述数据:
DECLARE @Temp TABLE
(
[ID] INT IDENTITY(1, 1) ,
[NAME] VARCHAR(30) ,
[PARENTID] INT,
[STATUS] BIT
)
INSERT INTO @Temp
SELECT 'Folder A' ,
0, 0
UNION
SELECT 'Folder B' ,
1, 0
UNION
SELECT 'Folder C' ,
2, 1
UNION
SELECT 'Folder D' ,
1, 0
UNION
SELECT 'Folder E' ,
4, 0
UNION
SELECT 'Folder G' ,
5, 0
UNION
SELECT 'Folder H' ,
6, 1
我有以下查询来获取status = 1
的记录 SELECT *
FROM @Temp WHERE [STATUS]=1
,它提供以下输出
ID NAME PARENTID STATUS
----------- ------------------------------ ----------- ------
3 Folder C 2 1
7 Folder H 6 1
我的目标是获取那些记录,这些记录是上述查询附带的记录的父项(直到parentid = 0)。即我想获得包含文件夹C和文件夹H的父项的输出:
ID NAME PARENTID STATUS
----------- ------------------------------ ----------- ------
1 Folder A 0 0
2 Folder B 1 0
3 Folder C 2 1
4 Folder D 1 0
5 Folder E 4 0
6 Folder G 5 0
7 Folder H 6 1
答案 0 :(得分:0)
DECLARE @Temp TABLE
(
[ID] INT IDENTITY(1, 1) ,
[NAME] VARCHAR(30) ,
[PARENTID] INT ,
[STATUS] BIT
)
INSERT INTO @Temp
SELECT 'Folder A' ,
0 ,
0
UNION
SELECT 'Folder B' ,
1 ,
0
UNION
SELECT 'Folder C' ,
2 ,
1
UNION
SELECT 'Folder D' ,
1 ,
0
UNION
SELECT 'Folder E' ,
4 ,
0
UNION
SELECT 'Folder G' ,
5 ,
1
UNION
SELECT 'Folder H' ,
6 ,
0
CREATE TABLE #TempTable
(
[RowIndex] INT IDENTITY(1, 1) ,
[ID] INT ,
[ParentID] INT
)
DECLARE @TempIds TABLE ( [ID] INT )
INSERT INTO #TempTable
( [ID] ,
[ParentID]
)
SELECT [ID] ,
[ParentID]
FROM @Temp
WHERE [STATUS] = 1
DECLARE @intFlag INT
DECLARE @Count INT
SET @intFlag = 1
SELECT @Count = COUNT(1)
FROM @Temp
WHILE ( @intFlag <= @Count )
BEGIN
PRINT @intFlag
DECLARE @ID INT
SELECT @ID = [ParentID]
FROM #TempTable
WHERE RowIndex = @intFlag
SET @intFlag = @intFlag + 1;
WITH CTE
AS ( SELECT ID ,
ParentID
FROM @Temp
WHERE ID = @ID
UNION ALL
SELECT MainTbl.ID ,
MainTbl.ParentID
FROM @Temp MainTbl
INNER JOIN cte ON MainTbl.ID = cte.ParentID
)
INSERT INTO @TempIds
SELECT ID
FROM CTE
END
;WITH cte
AS ( SELECT DISTINCT
ID
FROM @TempIds
)
SELECT T.*
FROM cte
INNER JOIN @Temp T ON [T].ID = cte.ID
UNION
SELECT T1.*
FROM #TempTable TempTable
INNER JOIN @Temp T1 ON [TempTable].ID = T1.ID
DROP TABLE #TempTable
输出:
ID NAME PARENTID STATUS
----------- ------------------------------ ----------- ------
1 Folder A 0 0
2 Folder B 1 0
3 Folder C 2 1
4 Folder D 1 0
5 Folder E 4 0
6 Folder G 5 1
答案 1 :(得分:0)
我做了一个递归CTE - 我从底部开始,任何没有孩子的文件夹。从那里开始,我会在“GOOD”列中遇到“1”状态,并且清除从底部开始创建的重复项。
;WITH CTE AS
(
SELECT ID, NAME, PARENTID, STATUS GOOD, STATUS
FROM @Temp T1
WHERE NOT EXISTS (SELECT * FROM @Temp T2 WHERE T2.PARENTID = T1.ID)
UNION ALL
SELECT T.ID, T.NAME, T.PARENTID, T.STATUS | C.GOOD GOOD, T.STATUS
FROM @Temp T
JOIN CTE C
ON C.PARENTID = T.ID
)
SELECT DISTINCT ID, NAME, PARENTID, STATUS FROM CTE
WHERE GOOD = 1
ORDER BY ID ASC