考虑表格的子部分:
recId|Col1 |Val1 |Col2 |Val2
________________________________________
1|'Id' |'1' |NULL |NULL |
2|'EmpId'|'100' |'Id' |'1' |
3|'EmpId'|'101' |'Id' |'1' |
4|'KeyId'|'1110'|'EmpId'|'100' |
5|'EmpId'|'101' |'KeyId'|'1111'|
6|'Id' |'2' |NULL |NULL |
我想知道是否有办法从该表中拉出与第一行相关的所有记录,其中id = @id?
在此示例中,让@id = 1。
输出应包含行,其中上面示例表中的recId IN(1,2,3,4,5)(Id = 1由EmpId = 101的行共享,由IDId的行共享) = 1111,等等。
这可能吗?
感谢a comment suggestion,我研究了递归公用表表达式。
这是我当前的db<>fiddle。
DECLARE @id integer = 1;
;WITH cte
AS (
SELECT n=1,recid,col1,val1,col2,val2 from elbat
WHERE col1 = 'Id' AND val1 = CAST(@id AS varchar(10))
UNION ALL
SELECT n=n+1,r.recid,r.col1,r.val1,r.col2,r.val2
FROM cte p
INNER JOIN elbat r
ON r.col1 = p.col1
AND r.val1 = p.val1
OR r.col1 = p.col2
AND r.val1 = p.val2
OR r.col2 = p.col1
AND r.val2 = p.val1
OR r.col2 = p.col2
AND r.val2 = p.val2
WHERE r.recid <> p.recid AND p.n = n AND n<3
)
SELECT recid,col1,val1,col2,val2
FROM cte
ORDER BY recid;
结果为:
recid col1 val1 col2 val2
________________________________________
1 Id 1 null null
1 Id 1 null null
1 Id 1 null null
2 EmpId 222 Id 1
2 EmpId 222 Id 1
3 EmpId 223 Id 1
3 EmpId 223 Id 1
4 KeyId 4445 EmpId 222
5 EmpId 223 KeyId 4444
我不确定如何防止无限递归-我需要从当前迭代中排除早期迭代的结果。现在,“ n”限制了深度(通过数量的连接数量),但是如您所见,它在每次迭代中都重复使用了cte中的所有 all 行。
请协助我解决这个问题。谢谢。
答案 0 :(得分:0)
首先,您需要钥匙
SELECT Col1, Val1
FROM Yourtable t1
WHERE Col1 = 'Id'
AND Val1 = @id
现在获取与该键匹配的所有行
SELECT *
FROM Yourtable t1
JOIN ( SELECT Col1, Val1
FROM Yourtable
WHERE col1 = 'Id'
AND Val1 = @id ) t2
ON t1.Col2 = t2.Col1
AND t1.Val2 = t2.Val1
使用递归CTE: SQL DEMO
DECLARE @id integer = 1;
;WITH cte AS (
SELECT n=1, recid, col1, val1, col2, val2
FROM elbat
WHERE col1 = 'Id' AND val1 = CAST(@id AS varchar(10))
UNION ALL
SELECT n=n+1, r.recid, r.col1, r.val1, r.col2, r.val2
FROM cte p
JOIN elbat r
ON r.col2 = p.col1 AND r.val2 = p.val1
)
SELECT n, recid,col1,val1,col2,val2
FROM cte
ORDER BY recid;