0

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

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 的子类别。

因此,父母需要按 AZ 排序,孩子需要作为一个组按 AZ 排序,并且在该组内,必须考虑按字母顺序排序的值。这不限于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 ????
4

2 回答 2

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

您当然可以ListSELECT列表中排除并仍然按其排序。

于 2016-06-06T16:47:15.193 回答
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
于 2016-06-07T09:02:20.163 回答