1

我有一张这样的桌子

ID               Node                  ParentID
1                 A                        0
2                 B                        1
3                 C                        1
4                 D                        2
5                 E                        2
6                 F                        3
7                 G                        3
8                 H                        3 
9                 I                        4
10                J                        4
11                K                        10
12                L                        11

我需要一个查询来生成一个“级别”字段,该字段显示特定节点的深度。下面的例子

ID               Node                  ParentID                  Level
1                 A                        0                         1
2                 B                        1                         2
3                 C                        1                         2
4                 D                        2                         3
5                 E                        2                         3
6                 F                        3                         4
7                 G                        3                         4
8                 H                        3                         4 
9                 I                        4                         5
10                J                        4                         5
11                K                        10                        6
12                L                        11                        7
4

6 回答 6

1
Select Id,
       Node,
       ParentID,
       Dense_Rank() Over(Order by ParentID) as Level 
       from Table_Name

SQL 小提琴演示

于 2013-07-24T08:54:15.600 回答
1

你可以使用DENSE_RANK函数

SELECT i.ID, p.Node, i.ParentID
    ,Dense_Rank() Over(Order by ParentID) as Level
FROM TableName AS i;

有关更多详细信息,请访问:http: //blog.sqlauthority.com/2007/10/09/sql-server-2005-sample-example-of-ranking-functions-row_number-rank-dense_rank-ntile/

于 2013-07-24T08:55:31.120 回答
1

在这里,您需要通过分组来设置级别,ParentID然后通过 连接两个表ParentID

WITH CTE (ParentID, Level)
AS (
    SELECT ParentID
         , Row_Number() OVER (ORDER BY ParentID) AS Level
      FROM Table1
     GROUP BY ParentID
)
SELECT t1.ID, t1.Node, t1.ParentID, CTE.Level
FROM Table1 t1 
JOIN CTE ON t1.ParentID = CTE.ParentID;

看到这个 SQLFiddle


更新:(对于 MySQL - 只是为了帮助别人)

要在 MySQL 中执行相同操作,请尝试像这样获取行号:

SELECT t1.ID, t1.Node, t1.ParentID, Tbl.Level
FROM Table1 t1 
JOIN
(
  SELECT @Level:=@Level+1 AS Level , ParentID 
  FROM (SELECT DISTINCT ParentID FROM Table1) t
, (SELECT @Level:=0) r
 ORDER BY ParentID
) Tbl
 ON t1.ParentID = Tbl.ParentID;

看到这个 SQLFiddle

于 2013-07-24T09:23:37.597 回答
1

我认为正确的方法是获取父级别并在插入数据时将其增加 1,因为所有其他方法在性能方面都是昂贵的。

于 2013-07-24T09:01:31.960 回答
1

就像是:

;with tree (ID, ParentID, Level)
as (
    select ID, ParentID, 1 from TableName where ParentID = 0
    union all
    select t.ID, t.ParentID, 1 + tree.Level
    from Tree join TableName t on t.ParentID = Tree.ID
)
select ID, Level from Tree
于 2013-07-24T09:18:49.203 回答
1

尝试这个

CREATE TABLE #Table1
    ([ID] int, [Node] varchar(1), [ParentID] int)
;

INSERT INTO #Table1
    ([ID], [Node], [ParentID])
VALUES
    (1, 'A', 0),
    (2, 'B', 1),
    (3, 'C', 1),
    (4, 'D', 2),
    (5, 'E', 2),
    (6, 'F', 3),
    (7, 'G', 3),
    (8, 'H', 3),
    (9, 'I', 4),
    (10, 'J', 4),
    (11, 'K', 10),
    (12, 'L', 11)
;

;WITH CTE ([ID], [ParentID], [Node], [Level])
as (
    SELECT [ID], [ParentID], [Node], 1 FROM #Table1 WHERE ParentID = 0
    UNION all
    select t.[ID], t.[ParentID], t.[Node], 1 + c.[Level]
    from CTE c inner join #Table1 t ON t.[ParentID] = c.[ID]
)
select ID, [Node], [ParentID], [Level] from CTE
ORDER BY [Node]


DROP TABLE #Table1
于 2013-07-24T09:30:02.367 回答