将相同的SNo分配给父级及其子级

时间:2013-08-07 07:02:24

标签: sql sql-server sql-server-2008

我有一个名为“TmpTable”的表,这个表有父子关系,表有数据如下:

Id | Name      | ParentId
 1   PCs         0
 2   MACs        1
 3   Keyboard    0
 4   Mouse       0
 5   Screen      3
 6   Keyboard    4
 7   Mouse       0
 8   Screen      0
 9   Key         0          
 10  xyz         9          

现在我想选择一列显示序列号,其中父和子具有相同的S.No.并且没有任何孩子的S.No.增加,结果将如下:

Id | Name      | ParentId | SNo
 1   PCs         0           1  
 2   MACs        1           1
 3   Keyboard    0           2
 4   Mouse       0           3
 5   Screen      3           2
 6   Keyboard    4           3
 7   Mouse       0           4
 8   Screen      0           5
 9   Key         0           6
 10  xyz         9           6

如何归档此结果请指导/帮助我。

4 个答案:

答案 0 :(得分:6)

您可以将DENSE_RANK()功能与ORDER BY CASE结合使用:

SELECT *, DENSE_RANK() OVER (ORDER BY CASE WHEN ParentID = 0 THEN ID ELSE ParentID END) 
FROM TmpTable
ORDER BY Id

<强> SQLFiddle DEMO

答案 1 :(得分:2)

你可以这样试试。

;with cte as 
(Select Row_Number() Over(Order by Id) as Row,Id from Table1 where Parentid=0
)
Select A.*,b.row as Sno from Table1 A inner join
cte as b on b.id=a.parentid or (b.id=a.id and a.parentid=0) order by a.id;

Sql Fiddle Demo

答案 2 :(得分:1)

这是n-depth的全面解决方案:

;WITH src AS (
    SELECT id=1, pid=0
    UNION ALL SELECT id=2, pid=1
    UNION ALL SELECT id=3, pid=0
    UNION ALL SELECT id=4, pid=0
    UNION ALL SELECT id=5, pid=3
    UNION ALL SELECT id=6, pid=4
    UNION ALL SELECT id=7, pid=0
    UNION ALL SELECT id=8, pid=0
    UNION ALL SELECT id=9, pid=0
    UNION ALL SELECT id=10, pid=9
),
rcte AS (
    SELECT id, pid, sno = ROW_NUMBER() OVER (ORDER BY id) 
    FROM src WHERE pid=0
    UNION ALL
    SELECT s.id, s.pid, r.sno
    FROM 
        rcte r
        JOIN src s 
            ON s.pid = r.id
    WHERE s.pid != 0 
)
SELECT *
FROM rcte
ORDER BY id

答案 3 :(得分:0)

这也可以通过JOIN完成。我认为这可能对MYSQL有帮助,因为它没有窗口函数

SELECT 
  DISTINCT 
  m1.id,
  m1.name,
  m1.parentid,
  1 + count( m2.id ) as sno
FROM
  mytable m1 
  LEFT JOIN mytable m2 on ( ( m1.parentid = 0 AND m2.parentid = 0 AND m2.id < m1.id)
                              OR ( m2.parentid = 0 AND m2.id < m1.parentid ) )
GROUP BY
  m1.id,
  m1.name,
  m1.parentid

SQLFIDDLE

注意:假设您的父母总是id小于childs