我有一个父子关系表,如下所示:
ContractID ContractIdRef
---------- -------------
1 null
2 1
3 1
4 2
5 4
10 null
11 10
12 11
15 null
16 12
我想要如下结果:
ContractID ContractIdRef rw
----------- -------------- ---
1 null 1
2 1 1
3 1 1
4 2 1
5 4 1
10 null 10
11 10 10
12 11 10
15 null 15
16 12 10
在上面的结果中,我想指定父行的每一行。
感谢
答案 0 :(得分:2)
正如您在 TAGS Comman Table Expression
中所提到的那样
;WITH REC_CTE
AS (SELECT [contractid],
[ContractIdRef],
[contractid] AS rw
FROM Yourtable
WHERE [contractidref] IS NULL
UNION ALL
SELECT T.[contractid],
T.[contractidref],
c.rw
FROM Yourtable AS T
INNER JOIN REC_CTE C
ON T.[contractidref] = c.[contractid]
WHERE T.[contractid] <> T.[contractidref])
SELECT [contractid],
[contractidref],
rw
FROM REC_CTE
ORDER BY [contractid]
架构设置
If object_id('tempdb.dbo.#Yourtable') is not null
DROP table #Yourtable
CREATE TABLE #Yourtable
([ContractID] INT, [ContractIdRef] INT);
示例数据
INSERT INTO #Yourtable
([ContractID], [ContractIdRef])
VALUES
('1', NULL),
('2', '1'),
('3', '1'),
('4', '2'),
('5', '4'),
('10', NULL),
('11', '10'),
('12', '11'),
('15', NULL),
('16', '12');
查询
;WITH REC_CTE
AS (SELECT [ContractID],
[ContractIdRef] as [ContractIdRef],
[ContractID] AS rw
FROM #Yourtable where [ContractIdRef] is null
UNION ALL
SELECT T.[ContractID],
T.[ContractIdRef],
c.rw
FROM #Yourtable AS T
INNER JOIN REC_CTE c
ON T.[ContractIdRef] = c.[ContractID]
WHERE T.[ContractID] <> T.[ContractIdRef])
SELECT [ContractID],
[ContractIdRef],
rw
FROM REC_CTE
ORDER BY [ContractID]
结果
+-----------+-------------+----+
|ContractID |ContractIdRef| rw |
+-----------+-------------+----+
|1 |NULL | 1 |
|2 |1 | 1 |
|3 |1 | 1 |
|4 |2 | 1 |
|5 |4 | 1 |
|10 |NULL | 10 |
|11 |10 | 10 |
|12 |11 | 10 |
|15 |NULL | 15 |
|16 |12 | 10 |
+-----------+-------------+----+
答案 1 :(得分:0)
with Q as(
select ContractID, ContractIdRef, ContractID as root
from childs
where ContractIdRef is null
union all
select C.ContractID, C.ContractIdRef, Q.root
from Q, childs C
where C.ContractIdRef=Q.ContractID
)
select * from Q
order by ContractID
在MS SQL 2014上测试。
对于Postgresql,需要在'with'后添加'递归'字样。 Test on sqlfiddle.com
对于Oracle第一行写为with Q(ContractID,ContractIdRef,root)
。