Sql Hierarchy ID Sorting By Level

◇◆丶佛笑我妖孽 提交于 2020-01-13 03:37:09

问题


Is it possible to sort sql data in a hierarchy by it's hierarchy id, and then for each level sort it say alphabetically?

So say we have an Employees Table that lists the organizational hierarchy based on the Employees ID

You have Bob (5) who has Phil (17) and Charlie(28) Reporting to him, and Josie (6) has Tyler (15) and Mike (56) Reporting to her.

If you sort it by HierarchyID it will look like:

Bob (/5/)
--Phil (/5/17/)
--Charlie (/5/28/)
Josie (/6/)
--Tyler (/6/15/)
--Mike (/6/56/)

But It would probably make more sense to have it look like

Bob
--Charlie
--Phil
Josie
--Mike
--Tyler

Is this possible without it getting too convoluted?


回答1:


--Will this work? this is taken from Sorting tree with other column in SQL Server 2008

DECLARE @table TABLE (id INT NOT NULL PRIMARY KEY, name NVARCHAR(4000) NOT NULL, path HIERARCHYID)

INSERT
INTO    @table
VALUES  
        (1, 'People', '/'),
        (2, 'Girls', '/1/'),
        (3, 'Boys', '/2/'),
        (4, 'Zoey', '/1/1/'),
        (5, 'Kate', '/1/2/'),
        (6, 'Monica', '/1/3/'),
        (7, 'Mark', '/2/1/'),
        (8, 'David', '/2/2/')

;WITH   q AS
        (
        SELECT  *, HIERARCHYID::Parse('/') AS newpath
        FROM    @table
        WHERE   path = HIERARCHYID::GetRoot()
        UNION ALL
        SELECT  t.*, HIERARCHYID::Parse(q.newpath.ToString() + CAST(ROW_NUMBER() OVER (ORDER BY t.name) AS NVARCHAR(MAX)) + '/')
        FROM    q
        JOIN    @table t
        ON      t.path.IsDescendantOf(q.path) = 1
                AND t.path.GetLevel() = q.path.GetLevel() + 1
        )
SELECT  replicate(convert(nvarchar, '-'), q.path.GetLevel()) + q.name /*+ '(' + q.newpath.ToString() + ')'*/
FROM    q
ORDER BY
        newpath



回答2:


This is the solution I've found

declare @oldId hierarchyid, @newId hierarchyid, @parent hierarchyid

select @oldId = id_node, @parent = id_node.GetAncestor(1)
from gbs.T_Hierarchy_Activities ha
where ID = @ID_Object

select @newId = @oldId.GetReparentedValue(@oldId, ID_Node) from (
    select row_number() over(order by id_node) rn, id_node
    from gbs.T_Hierarchy_Activities ha
        cross join (select * from common.FX_Permissions() where ID_Feature = 10) p
    where ID_Node.IsDescendantOf(@oldId.GetAncestor(1)) = 1
        and ID_Level = @oldId.GetLevel()
        and ha.ID_Office = p.ID_Office
) a
where rn = @NewPosition

update gbs.T_Hierarchy_Activities
set ID_Node = case when ID_Node = @oldId then @newId else @oldId end
where ID_Node in (@oldId, @newId)



回答3:


Unless I'm misunderstanding something, you can just add a secondary sort field to the ORDER BY clause. For example:

SELECT * FROM Employees ORDER BY HierarchyID, Name


来源:https://stackoverflow.com/questions/8899230/sql-hierarchy-id-sorting-by-level

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!