SQL树层次结构顺序排列,但显示为树

时间:2015-04-24 11:41:03

标签: sql sql-server

这是existing question的扩展,用于创建排序顺序父子层次结构。

如何按字母顺序对表格进行排序,但所有子节点都处于正确的位置? 因此,在为它们分配了正确的排序顺序后,父节点不按字母顺序排列,并且每个子级别都不是。

注意:我使用的实际数据底部没有数字,它们只是为了说明层次结构的级别(例如,piperoni在比萨饼下)

pizza   0.1
piperoni    0.1.4
cheese  0.1.5
extra cheese    0.1.5.7
vegetariana 0.1.6
burger  0.2
coffee  0.3

如何将其更改为此?

burger  0.1
coffee  0.2
pizza   0.3
cheese  0.3.1
extra cheese    0.3.1.1
piperoni    0.3.2
vegetariana 0.3.3

See This

1 个答案:

答案 0 :(得分:0)

http://sqlblog.com/blogs/john_paul_cook/archive/2009/10/03/displaying-hierarchical-data-indenting-the-output.aspx

约翰保罗库克写了一个有用的查询,我本周早些时候实际使用过

简而言之,它使用递归CTE并使用字符串连接来设置排序

;WITH BOMcte(ComponentID, Name, PerAssemblyQty, BOMLevel, ProductAssemblyID, Sort) 
AS 
( 
    SELECT b.ComponentID, 
       CAST(p.Name as nvarchar(100)), 
       b.PerAssemblyQty, 
       b.BOMLevel, 
       b.ProductAssemblyID,
       CAST('\' + p.Name as nvarchar(254)) 
FROM Production.BillOfMaterials AS b 
INNER JOIN Production.Product p 
on b.ComponentID = p.ProductID 
WHERE b.EndDate IS NULL  -- only retrieve components still being used 
and b.ComponentID = 775  -- specify a component to explode 
UNION ALL 
SELECT b.ComponentID, 
       CAST(REPLICATE ('|    ' , b.BOMLevel) + p.Name as nvarchar(100)), 
       b.PerAssemblyQty, 
       b.BOMLevel, 
       b.ProductAssemblyID, 
       CAST(cte.Sort + '\' + p.Name as nvarchar(254)) 
FROM Production.BillOfMaterials as b 
INNER JOIN Production.Product p 
on b.ComponentID = p.ProductID 
INNER JOIN BOMcte AS cte 
ON b.ProductAssemblyID = cte.ComponentID 
WHERE b.EndDate IS NULL  -- only retrieve components still being used 
) 
SELECT Name, PerAssemblyQty 
FROM BOMcte 
ORDER BY Sort;

这就是我实现它的方式

WITH    Counts
      AS (
           SELECT   parent_ID ,
                    COUNT(id) AS cnt
           FROM     Contact_Heirarchy
           WHERE    Contact_Heirarchy.Discontinue_Date IS NULL
           GROUP BY Parent_Id
         ),
    Employee ( ID, [ParentId], Contact_ID, Name, ImmediateChildren )
      AS (
           SELECT   Company_Heirarchy_ID ,
                    Contact_Heirarchy.Parent_ID ,
                    c.contact_ID ,
                    c.Reporting_Name AS name ,
                    ISNULL(cn.cnt, 0) AS ImmediateChildren
           FROM     Contact_Heirarchy
                    LEFT OUTER JOIN Contact c ON Contact_Heirarchy.contact_ID = c.Contact_ID
                    LEFT OUTER JOIN Counts cn ON Contact_Heirarchy.Company_Heirarchy_ID = cn.parent_id
           WHERE    Contact_Heirarchy.Discontinue_Date IS NULL
         ),
    Tree
      AS (
           SELECT   [Id] ,
                    [ParentId] ,
                    Contact_ID ,
                    0 AS [TreeLevel] ,
                    CAST('\' + ( cast( 999 - ImmediateChildren as varchar(3)) ) + Name AS VARCHAR(1000)) AS Sort ,
                    CAST(REPLICATE('|    ', 0) + Name AS NVARCHAR(100)) Hierarchy ,
                    ParentNode.ImmediateChildren
           FROM     Employee AS ParentNode 
           WHERE    ( Contact_ID in(@contactID))
           UNION ALL
           SELECT   ChildNode.[Id] ,
                    ChildNode.[ParentId] ,
                    ChildNode.Contact_ID ,
                    LIT.[TreeLevel] + 1 AS [TreeLevel] ,
                    CAST(LIT.sort + '\' + (cast( 999 - ChildNode.ImmediateChildren as varchar(3)) ) + Name AS VARCHAR(1000)) AS Sort ,
                    CAST(REPLICATE('|    ', LIT.TreeLevel + 1) + Name AS NVARCHAR(100)),
                    ChildNode.ImmediateChildren
           FROM     Employee AS ChildNode 
                    INNER JOIN [Tree] LIT ON ( ChildNode.[ParentId] = LIT.[Id] )
           WHERE    ( ChildNode.[ParentId] IS NOT NULL )
         )
SELECT  Tree.* ,
        c.Reporting_Name AS Contact
FROM    Tree
        INNER JOIN Contact c ON Tree.Contact_ID = c.Contact_ID
ORDER BY Tree.Sort
相关问题