按父组和子组顺序排列父子记录

时间:2015-03-26 09:10:01

标签: sql-server tsql sorting multiple-columns

我需要通过特定的两个相关列对查询结果进行排序。我的表是:

Row no | Col 1 | Col 2 | Col 3 | Col 4
    1  |   1   |  X    |  1    |  5
    2  |   2   |  Y    |  1    |  6
    3  |   5   |  Z    |  2    |  7
    4  |   6   |  T    |  2    |  0
    5  |   7   |  T    |  3    |  0
    6  |   6   |  W    |  2    |  0

Col 4中的值表示与Col 1关联的子记录。

因此对于Row no = 1,下一个子记录是第3行,其中Col 1保留第一行Col 4的值。

第3行的下一个子行是第5行,基于Col 1Col 4之间的链接。

我想回复此结果:

Row no | Col 1 | Col 2 | Col 3 | Col 4
    1  |   1   |  X    |  1    |  5
    3  |   5   |  Z    |  2    |  7
    5  |   7   |  T    |  3    |  0    
    2  |   2   |  Y    |  1    |  6
    4  |   6   |  T    |  2    |  0
    6  |   6   |  W    |  2    |  0 

所以我希望排序显示一个Parent行,然后显示它的子行,然后再转到下一个顶级Parent行。

1 个答案:

答案 0 :(得分:1)

您可以使用Recursive CTE实现所需的目标,以查找所有父记录并将其链接到其子记录。

虚拟桌面设置:

CREATE TABLE #Table1
    (
      [Row no] INT ,
      [Col 1] INT ,
      [Col 2] VARCHAR(1) ,
      [Col 3] INT ,
      [Col 4] INT
    );

INSERT  INTO #Table1
        ( [Row no], [Col 1], [Col 2], [Col 3], [Col 4] )
VALUES  ( 1, 1, 'X', 1, 5 ),
        ( 2, 2, 'Y', 1, 6 ),
        ( 3, 5, 'Z', 2, 7 ),
        ( 4, 6, 'T', 2, 0 ),
        ( 5, 7, 'T', 3, 0 ),
        ( 6, 6, 'W', 2, 0 );

递归CTE:

;WITH    cte
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( ORDER BY t1.[Col 1] ) GroupNo
               FROM     #Table1 t1
               WHERE    t1.[Col 1] NOT IN ( SELECT  [Col 4] FROM #Table1 )
               UNION ALL
               SELECT   t.* ,
                        cte.GroupNo
               FROM     #Table1 t
                        INNER JOIN cte ON cte.[Col 4] = t.[Col 1]
             )
    SELECT  *
    FROM    cte
    ORDER BY cte.GroupNo , cte.[Row no]

DROP TABLE #Table1

这将2个查询与UNION ALL组合在一起。第一个查询查找[Col 1]中未显示[Col 4]值的顶级项目:

WHERE    t1.[Col 1] NOT IN ( SELECT  [Col 4] FROM #Table1 )

第二个查询使用此JOIN

在第一个查询中查找子记录
INNER JOIN cte ON cte.[Col 4] = t.[Col 1]

对于排序,我使用以下内容将第一个查询的结果给出GroupNo,稍后会用它来订购记录:

ROW_NUMBER() OVER ( ORDER BY t1.[Col 1] ) GroupNo