SQL:如何查找叶子行?

arm*_*men 5 sql sql-server sql-server-2012

我有一个自我相关的表myTable像:

ID | RefID
----------
 1 | NULL
 2 | 1
 3 | 2
 4 | NULL
 5 | 2
 6 | 5
 7 | 5
 8 | NULL
 9 | 7
Run Code Online (Sandbox Code Playgroud)

我需要在任何深度上获得叶子行

根据上表,结果必须是:

ID | RefID
----------
 3 | 2
 4 | NULL
 6 | 5
 8 | NULL
 9 | 7
Run Code Online (Sandbox Code Playgroud)

谢谢

PS:深度可能会有所不同,这里的例子非常小

以下是样本数据的直观演示

xle*_*ier 8

尝试:

SELECT id,
       refid
FROM   mytable t
WHERE  NOT EXISTS (SELECT 1
                   FROM   mytable
                   WHERE  refid = t.id)  
Run Code Online (Sandbox Code Playgroud)

  • 用更多数据查看我的答案 (2认同)

gbn*_*gbn 7

DECLARE @t TABLE (id int NOT NULL, RefID int NULL);

INSERT @t VALUES (1, NULL), (2, 1),  (3, 2),  (5, NULL), 
             (6, 5), (4, NULL), (7, 5), (8, NULL), (9, 8), (10, 7);

WITH CTE AS
(
    -- top level
    SELECT id, RefID, id AS RootId, 0 AS CTELevel FROM @t WHERE REfID IS NULL
    UNION ALL
    SELECT T.id, T.RefID, RootId, CTELevel + 1 FROM @t T JOIN CTE ON T.RefID = CTE.id
), Leafs AS
(
    SELECT
        id, RefID, DENSE_RANK() OVER (PARTITION BY CTE.RootId ORDER BY CTELevel DESC) AS Rn
    FROM CTE
)
SELECT
    id, RefID
FROM
    Leafs
WHERE
    rn = 1
Run Code Online (Sandbox Code Playgroud)

  • 对于像这样简单的事情,递归是不必要的.你只需要检查每一行孩子是否有自己的孩子.其他两个答案工作正常 - 即使您的样本数据.然而,这个CTE缺少第7,5行? (4认同)
  • @XLAnt我撤回了我以前的评论.更正:如果想要查找作为特定项的后代的所有叶节点,则需要递归.在这种情况下不需要,OP似乎想要结构的所有叶子. (4认同)