在这里找到一个有趣的问题。
ResultID ParentID ValueX
--------------------------
1 0 GrandParent
2 1 Parent1
3 1 Parent2
4 2 Child1
5 2 Child2
6 3 Child3
7 3 Child4
我希望我的查询结果集如下所示:
ResultID ParentID ValueX
--------------------------
1 0 GrandParent
2 1 Parent1
4 2 Child1
5 2 Child2
3 1 Parent2
6 3 Child3
7 3 Child4
如果ParentID为0,则表示它是主要类别。如果ParentID大于0,则表示它是次要类别,即父级的子级。
因此父母需要被命令A-Z并且孩子需要被命令A-Z作为一个组,并且在该组内必须考虑按字母顺序排序的值。 这不仅限于3个级别,可以持续到10级。
你能帮我正确订购吗?
WITH resultset (resultid, parentid, valuex) AS (
SELECT 1,0,'Grandparent' FROM dual UNION ALL
SELECT 2,1,'Parent1' FROM dual UNION ALL
SELECT 3,1,'Parent2' FROM dual UNION ALL
SELECT 4,2,'Child1' FROM dual UNION ALL
SELECT 5,2,'Child2' FROM dual UNION ALL
SELECT 6,3,'Child3' FROM dual UNION ALL
SELECT 7,3,'Child4' FROM dual )
SELECT ResultID , ParentID, ValueX
FROM resultset
ORDER BY ????
答案 0 :(得分:1)
您可以使用递归cte创建路径列表,以下是SQL Server语法,但oracle应该类似:
;with cte AS (SELECT ResultID,ParentID,ValueX, List = CAST(ResultID AS VARCHAR(MAX))
FROM #Table1
WHERE ParentID = 0
UNION ALL
SELECT a.ResultID,a.ParentID,a.ValueX, List = b.List + ','+CAST(a.ResultID AS VARCHAR(MAX))
FROM #Table1 a
JOIN cte b
ON a.ParentID = b.ResultID
)
SELECT *
FROM cte
ORDER BY List
输出:
ResultID ParentID ValueX List
1 0 GrandParent 1
2 1 Parent1 1,2
4 2 Child1 1,2,4
5 2 Child2 1,2,5
3 1 Parent2 1,3
6 3 Child3 1,3,6
7 3 Child4 1,3,7
您当然可以从List
列表中排除SELECT
,然后依次排序。
答案 1 :(得分:1)
您可以通过自联接来生成要从层次结构中订购的值列表,如下面的代码所示。我已经扩展到为原始示例添加额外级别的层次结构,以显示这将如何工作。显然,这取决于知道生成合理计划的层次结构级别的数量(例如,您可以总是执行10个级别,但如果您的示例中只有3个级别的层次结构,那么这将是一个很大的性能损失。)
进一步想到我想你可以使用EXEC语句来生成特定层次结构级别所需的SQL,而不是像下面那样手动生成(这将有一些优化,例如我们知道条目在L3处没有任何内容它在L4也没有任何东西。
WITH resultset (resultid, parentid, valuex) AS (
SELECT 1,0,'Grandparent' UNION ALL
SELECT 2,1,'Parent1' UNION ALL
SELECT 3,1,'Parent2' UNION ALL
SELECT 4,2,'Child1' UNION ALL
SELECT 5,2,'Child2' UNION ALL
SELECT 6,3,'Child3' UNION ALL
SELECT 7,3,'Child4' UNION ALL
SELECT 8,4,'Child1_Child1' UNION ALL
SELECT 9,7,'Child4_Child1' UNION ALL
SELECT 10,6,'Child3_Child1')
SELECT l1.resultid , l1.parentid, l1.valuex, l2.resultid l2val, l3.resultid l3val,l4.resultid l4val,
-- rewrite COALESCE so clearer how this matches the pattern below
CASE WHEN l4.resultid IS NULL THEN
CASE WHEN l3.resultid IS NULL THEN
CASE WHEN l2.resultid IS NULL THEN l1.valuex
ELSE l2.valuex END
ELSE l3.valuex END
ELSE l4.valuex END o1,
CASE WHEN l4.resultid IS NULL THEN
CASE WHEN l3.resultid IS NULL THEN
CASE WHEN l2.resultid IS NULL THEN ''
ELSE l1.valuex END
ELSE COALESCE (l2.valuex, l1.valuex, '') END
ELSE COALESCE (l3.valuex, l2.valuex, l1.valuex, '') END o2,
CASE WHEN l3.resultid IS NULL THEN ''
WHEN l4.valuex IS NULL THEN l1.valuex
ELSE l2.valuex END o3,
CASE WHEN l2.valuex IS NULL THEN ''
WHEN l4.valuex IS NULL THEN '' ELSE l1.valuex END o4
FROM resultset l1
left join resultset l2 on l1.parentid = l2.resultid
left join resultset l3 on l2.parentid = l3.resultid
left join resultset l4 on l3.parentid = l4.resultid
ORDER BY o1, o2, o3, o4
结果(格式错误道歉):
RESULTID PARENTID VALUEX L2VAL L3VAL L4VAL O1 O2 O3 O4
1 0 Grandparent (null) (null) (null) Grandparent
2 1 Parent1 1 (null) (null) Grandparent Parent1
4 2 Child1 2 1 (null) Grandparent Parent1 Child1
8 4 Child1_Child1 4 2 1 Grandparent Parent1 Child1 Child1_Child1
5 2 Child2 2 1 (null) Grandparent Parent1 Child2
3 1 Parent2 1 (null) (null) Grandparent Parent2
6 3 Child3 3 1 (null) Grandparent Parent2 Child3
10 6 Child3_Child1 6 3 1 Grandparent Parent2 Child3 Child3_Child1
7 3 Child4 3 1 (null) Grandparent Parent2 Child4
9 7 Child4_Child1 7 3 1 Grandparent Parent2 Child4 Child4_Child1