sql - 如何使用排序顺序列对层次结构进行排序
问题描述
我在 SQL 中有一个包含一些虚拟数据的层次结构:
HierarchyID ParentItemID SortOrder Name
1 NULL 99 Main Parent
2 1 80 Sub Parent 1
3 1 99 Sub Parent 2
4 2 99 Sub Parent 1 child 1
5 3 1 Sub Parent 2 child 1
6 2 89 Sub Parent 1 child 2
我怎样才能排序这个排序顺序驱动排序而不影响层次结构的逻辑?
例如,如果上面只是按 SortOrder 排序,那么层次结构本身就没有意义。Sub Parent 1 child 2 将出现在 Main Parent 上方,这是不允许的。
我们将其作为视觉呈现给用户。必须允许该用户对层次结构出现的顺序进行排序,而不会影响层次结构的逻辑。
我创建了以下构建树视图的 CTE:
WITH EntitiesCTE(ReportingHierarchyTypeID, ReportingHierarchyTypeCode, ReportingHierarchyItemID, Parent, Level, UltimateParent, HasChildren, Treepath, IsActive,ReportingHierarchySortOrder) AS
( SELECT RHT.ReportingHierarchyTypeID,
RHT.ReportingHierarchyTypeCode,
RHI.ReportingHierarchyItemID AS id,
RHI.ParentItemID,
0 AS Level,
RHI.ReportingHierarchyItemID as UltimateParent,
CASE
WHEN RHI.ReportingHierarchyItemID in (select t.ParentItemID FROM MASTER.ReportingHierarchyItem t) THEN 1
ELSE 0
END AS HasChildren,
CAST(RHI.ItemCode AS VARCHAR(1024)) AS Treepath,
RHI.IsActive,
RHI.ReportingHierarchySortOrder
FROM MASTER.ReportingHierarchyItem RHI
INNER JOIN MASTER.ReportingHierarchyType RHT
on RHI.ReportingHierarchyTypeID = RHT.ReportingHierarchyTypeID
WHERE RHI.ParentItemID is null
UNION ALL
SELECT RHT.ReportingHierarchyTypeID,
RHT.ReportingHierarchyTypeCode,
RHI.ReportingHierarchyItemID AS id,
RHI.ParentItemID,
EntitiesCTE.Level + 1 AS Level,
EntitiesCTE.UltimateParent,
CASE
WHEN RHI.ReportingHierarchyItemID in (select t.ParentItemID FROM MASTER.ReportingHierarchyItem t) THEN 1
ELSE 0
END AS HasChildren,
CAST(EntitiesCTE.treepath + ' -> ' + CAST(RHI.ItemCode AS VARCHAR(1024)) AS VARCHAR(1024)) AS treepath,
RHI.IsActive,
RHI.ReportingHierarchySortOrder
FROM MASTER.ReportingHierarchyItem RHI
INNER JOIN MASTER.ReportingHierarchyType RHT
on RHI.ReportingHierarchyTypeID = RHT.ReportingHierarchyTypeID
INNER JOIN EntitiesCTE
ON EntitiesCTE.ReportingHierarchyItemID = RHI.ParentItemID
)
SELECT
a.*
,b.ReportingHierarchyTypeName
,e.ItemCode
,e.ItemName
,e.ParentItemID
,e.CompanyID
-- ,e.ReportingHierarchySortOrder
FROM EntitiesCTE a
INNER JOIN
MASTER.ReportingHierarchyType b
ON b.ReportingHierarchyTypeID = a.ReportingHierarchyTypeID
INNER JOIN MASTER.ReportingHierarchyItem e
ON e.ReportingHierarchyItemID = a.ReportingHierarchyItemID
WHERE a.ReportingHierarchyTypeID = e.ReportingHierarchyTypeID
--ORDER BY a.Treepath,a.ReportingHierarchySortOrder, Coalesce(a.parent,0)
ORDER BY a.Treepath, a.ReportingHierarchySortOrder ASC
但是我得到以下信息:
HierarchyID ParentItemID SortOrder Name
1 NULL 99 Main Parent
2 1 80 Sub Parent 1
4 2 99 Sub Parent 1 child 1
6 2 89 Sub Parent 1 child 2
3 1 99 Sub Parent 2
5 3 1 Sub Parent 2 child 1
要做到这一点,应该交换 HierarchyID 4 和 6。
解决方案
我将 Treeview 调整为以下内容并且它有效:
WITH EntitiesCTE(ReportingHierarchyTypeID, ReportingHierarchyTypeCode, ReportingHierarchyItemID, Parent, Level, UltimateParent, HasChildren, Treepath, IsActive,ReportingHierarchySortOrder, ReportingHierarchySortOrderPath) AS
( SELECT RHT.ReportingHierarchyTypeID,
RHT.ReportingHierarchyTypeCode,
RHI.ReportingHierarchyItemID AS id,
RHI.ParentItemID,
0 AS Level,
RHI.ReportingHierarchyItemID as UltimateParent,
CASE
WHEN RHI.ReportingHierarchyItemID in (select t.ParentItemID FROM MASTER.ReportingHierarchyItem t) THEN 1
ELSE 0
END AS HasChildren,
CAST(RHI.ItemCode AS VARCHAR(1024)) AS Treepath,
RHI.IsActive,
RHI.ReportingHierarchySortOrder,
CAST(RHI.ReportingHierarchySortOrder AS VARCHAR(1024)) AS ReportingHierarchySortOrderPath
FROM MASTER.ReportingHierarchyItem RHI
INNER JOIN MASTER.ReportingHierarchyType RHT
on RHI.ReportingHierarchyTypeID = RHT.ReportingHierarchyTypeID
WHERE RHI.ParentItemID is null
UNION ALL
SELECT RHT.ReportingHierarchyTypeID,
RHT.ReportingHierarchyTypeCode,
RHI.ReportingHierarchyItemID AS id,
RHI.ParentItemID,
EntitiesCTE.Level + 1 AS Level,
EntitiesCTE.UltimateParent,
CASE
WHEN RHI.ReportingHierarchyItemID in (select t.ParentItemID FROM MASTER.ReportingHierarchyItem t) THEN 1
ELSE 0
END AS HasChildren,
CAST(EntitiesCTE.treepath + ' -> ' + CAST(RHI.ItemCode AS VARCHAR(1024)) AS VARCHAR(1024)) AS treepath,
RHI.IsActive,
RHI.ReportingHierarchySortOrder,
CAST(EntitiesCTE.ReportingHierarchySortOrderPath + ' -> ' + CAST(RHI.ReportingHierarchySortOrder AS VARCHAR(1024)) AS VARCHAR(1024)) AS ReportingHierarchySortOrderPath
FROM MASTER.ReportingHierarchyItem RHI
INNER JOIN MASTER.ReportingHierarchyType RHT
on RHI.ReportingHierarchyTypeID = RHT.ReportingHierarchyTypeID
INNER JOIN EntitiesCTE
ON EntitiesCTE.ReportingHierarchyItemID = RHI.ParentItemID
)
SELECT
a.*
,b.ReportingHierarchyTypeName
,e.ItemCode
,e.ItemName
,e.ParentItemID
,e.CompanyID
-- ,e.ReportingHierarchySortOrder
FROM EntitiesCTE a
INNER JOIN
MASTER.ReportingHierarchyType b
ON b.ReportingHierarchyTypeID = a.ReportingHierarchyTypeID
INNER JOIN MASTER.ReportingHierarchyItem e
ON e.ReportingHierarchyItemID = a.ReportingHierarchyItemID
WHERE a.ReportingHierarchyTypeID = e.ReportingHierarchyTypeID
ORDER BY a.ReportingHierarchySortOrderPath ASC
推荐阅读
- activemq-artemis - 当 deployBridge 使用 DEFAULT_CONFIRMATION_WINDOW_SIZE(-1) 时,无法在确认窗口大小 < 0 错误的连接上设置确认处理程序
- python - 使用 Python 弹性客户端插入新文档会引发非法参数异常
- c# - 添加控制器 -> 无法加载“https://www.nuget.org/packages/Newtonsoft.json”的服务索引
- apache-spark - 使用 dropduplicates 时保持最后?
- f# - 在 F# 中抽象 DU 案例的最佳方法?
- react-native - 在 UIManager 中找不到 RNCAndroidDropdownPicker
- html - BootStrap 5.0 beta 1 轮播幻灯片不工作
- django - 如何从 URL 中获取一个数字并在 django 中检查它的长度?
- c - 程序输出说明
- spring - @Service Spring 单元测试太慢了