题
我在MS SQL以下递归表值函数,为了检索对象的从数据库中一个层次结构:
WITH tmpField (ParentNum, ChildNum, FieldNum, FieldDescr, Iteration) AS
(
SELECT Field.ParentNum, Field.ChildNum, Field.FieldNum, Field.FieldDescr, 1
FROM Field
WHERE Field.ParentNum = @ParentNum
UNION ALL
SELECT Field.ParentNum, Field.ChildNum, Field.FieldNum, Field.FieldDescr, tmpField.Iteration + 1
FROM Field INNER JOIN
tmpField on Field.ParentNum = tmpField.ChildNum
)
SELECT DISTINCT ParentNum AS ParentNum, ChildNum AS ChildNum, FieldNum, FieldDescr
FROM tmpField
我想修改它以下述方式:
在最后的迭代,当没有更多的“孩子”,我想ChildNum
领域有FieldNum
的价值。在所有以前的迭代,ChildNum
应该有ChildNum
字段的值,因为它是现在。
任何人都可以提供一个方法来实现这一点,使用上述查询作为起点?
请注意:尽管它的名字,现场ChildNum
没有引用行的任何子女,但应理解为该行的标识符。
解决方案
当没有更多的孩子就意味着ChildNum为NULL这样:
...
UNION ALL
SELECT Field.ParentNum,
COALESCE(Field.ChildNum, Field.FieldNum) ChildNum,
Field.FieldNum,
...
编辑:(以下大安评语)
确定,在这种情况下,我们可以检查ChildNum '孩子' 计数:
...
UNION ALL
SELECT F1.ParentNum,
CASE WHEN (SELECT COUNT(1)
FROM FIELD F2
WHERE F2.ParentNum = F1.ChildNum) = 0
THEN F1.FieldNum
ELSE F1.ChildNum
END ChildNum,
F1.FieldNum, F1.FieldDescr, tmpField.Iteration + 1
FROM Field F1 INNER JOIN
tmpField on F1.ParentNum = tmpField.ChildNum
...
EDIT2:
让我们外移动的检查:
WITH tmpField (ParentNum, ChildNum, FieldNum, FieldDescr, Iteration) AS
(
SELECT Field.ParentNum, Field.ChildNum, Field.FieldNum, Field.FieldDescr, 1
FROM Field
WHERE Field.ParentNum = @ParentNum
UNION ALL
SELECT Field.ParentNum, Field.ChildNum, Field.FieldNum, Field.FieldDescr, tmpField.Iteration + 1
FROM Field INNER JOIN
tmpField on Field.ParentNum = tmpField.ChildNum
)
SELECT DISTINCT ParentNum AS ParentNum,
CASE WHEN EXISTS (SELECT NULL
FROM Field f
WHERE tmpField.ChildNum = f.ParentNum)
THEN tmpField.ChildNum
ELSE tmpField.FieldNum
END ChildNum,
FieldNum,
FieldDescr
FROM tmpField
其他提示
这应该返回你需要的数据。 我删除重复,你不要用到它。
JOIN VERSION
;WITH tmpField (ParentNum, ChildNum, FieldNum, FieldDescr) AS
(
SELECT f.ParentNum, f.ChildNum, f.FieldNum, f.FieldDescr
FROM Field f
WHERE f.ParentNum = @ParentNum
UNION ALL
SELECT f.ParentNum, f.ChildNum, f.FieldNum, f.FieldDescr
FROM Field f
INNER JOIN tmpField on f.ParentNum = tmpField.ChildNum
)
SELECT t.ParentNum AS ParentNum,
Case When p.ParentNum is Null
Then t.FieldNum
Else t.ChildNum
End AS ChildNum,
t.FieldNum,
t.FieldDescr
FROM tmpField t
Left Join (Select distinct ParentNum From Field) p on t.ChildNum=p.ParentNum
或
SUBQUERY VERSION(修改以使用EXISTS代替COUNT)
;WITH tmpField (ParentNum, ChildNum, FieldNum, FieldDescr) AS
(
SELECT f.ParentNum, f.ChildNum, f.FieldNum, f.FieldDescr
FROM Field f
WHERE f.ParentNum = @ParentNum
UNION ALL
SELECT f.ParentNum, f.ChildNum, f.FieldNum, f.FieldDescr
FROM Field f
INNER JOIN tmpField on f.ParentNum = tmpField.ChildNum
)
SELECT t.ParentNum AS ParentNum,
Case When Exists(Select * from Field p Where t.ChildNum=p.ParentNum)
Then t.ChildNum
Else t.FieldNum
End AS ChildNum,
t.FieldNum,
t.FieldDescr
FROM tmpField t
不隶属于 StackOverflow