按(parent、child 组)和值按字母顺序排序

Order by (parent, child group) and values alphabetically

在这里发现了一个有趣的问题。

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,则表示它是次要类别,parent.

的 child

所以 parents 需要排序 A-Z 并且 children 需要排序 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 ????

您可以使用递归cte创建路径列表,以下是SQL服务器语法,但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

您当然可以从 SELECT 列表中排除 List,但仍按它排序。

您可以通过自连接生成要排序的层次结构中的值列表来执行此操作,如下面的代码所示。我已经扩展为向原始示例添加一个额外的层次结构级别以显示它是如何工作的。显然,这取决于了解层次结构级别的数量以生成合理的计划(例如,您始终可以执行 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