需要查询才能将“级别”插入到相邻列表中

时间:2013-07-24 08:51:26

标签: sql sql-server

我有一张像这样的桌子

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

6 个答案:

答案 0 :(得分:1)

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

SQL Fiddle Demo

答案 1 :(得分: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/

答案 2 :(得分:1)

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

答案 3 :(得分: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

答案 4 :(得分: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;

请参阅this 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;

请参阅this SQLFiddle

答案 5 :(得分: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