问题
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