【问题标题】:Recursive CTE to get top level results递归 CTE 以获得顶级结果
【发布时间】:2020-06-17 13:08:33
【问题描述】:

这是我当前的数据集。

| BIMUnique | Description                                | Quantity | SuperiorUnique | LineCode |
|-----------|--------------------------------------------|----------|----------------|-----------|
| 660084    | Top Level Order Description                | 1        | 0              | 01        |
| 660085    | Second Level Order Description             | 50       | 660084         | 01        |
| 660086    | Second Level Order Description w/sub order | 200      | 660084         | 02        |
| 660087    | Third Level Order Description              | 10       | 660086         | 07        |

我想要这样的东西

| Top Level Description       | Immediate Parent                           | Item Description                           | Navigation (LineCode Concatenation) | Qty |
|-----------------------------|--------------------------------------------|--------------------------------------------|-------------------------------------|-----|
| Top Level Order Description | 0                                          | Top Level Order Description                | 01                                  | 1   |
| Top Level Order Description | Top Level Order Description                | Second Level Order Description             | 01.01                               | 50  |
| Top Level Order Description | Top Level Order Description                | Second Level Order Description w/sub order | 01.02                               | 200 |
| Top Level Order Description | Second Level Order Description w/sub order | Third Level Order Description              | 01.02.07                            | 10  | 

我当前的 CTE 有两个问题 - 首先它不显示顶级父级,只显示直接。其次,ROW_NUMBER 只计算行数,不反映 LineCode。如果我的最终用户创建了 3 个列表项,然后删除了第 2 项,则系统不会返回并重新排序行号。

WITH bi AS 
    (
        SELECT  
          m.*, 
          CAST(ROW_NUMBER() OVER (ORDER BY m.LineCode) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS Tree
        FROM BidItems m with (nolock)
        WHERE m.SuperiorUnique = 0 AND m.JobUnique = '12591'

        UNION ALL

        SELECT  
          m.*,  
          bi.Tree + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY m.SuperiorUnique ORDER BY m.LineCode) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN
        FROM BidItems m with (nolock)
        JOIN bi ON m.SuperiorUnique = bi.BIMUnique
        WHERE m.JobUnique = '12591'
    )

SELECT 
  Job.Number,
  Job.Description,
  bi.Tree,
  bi.LineCode,
  bi.Description,
  bi.Quantity,
  bi.TotalCosts,
  bi.*
FROM Job AS job with (nolock)
INNER JOIN bi ON bi.JobUnique = Job.JOBUnique
INNER JOIN BidItems AS sup with (nolock) ON bi.SuperiorUnique = sup.BIMUnique
LEFT JOIN BidItemDetail AS bid with (nolock) ON bid.BidItemUnique = bi.BIMUnique

ORDER BY Bi.Tree

我们正在使用 MSSQL 2012

更新:LineOrder 应该是 LineCode。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012 hierarchical-query


    【解决方案1】:

    考虑以下查询,它从根遍历树到叶子。我真的不认为需要row_number() 来生成路径,这显然是由LineNumbers 组成的。

    with cte (TopLevelDescription, ImmediateParent, ItemDescription, Navigation, Qty, BIMUnique)
    as (
        select 
            Description, 
            cast(0 as varchar(60)), 
            Description, 
            cast(LineOrder as varchar(max)), 
            Qty, 
            BIMUnique 
        from BidItems
        where SuperiorUnique = 0
        union all
        select 
            c.TopLevelDescription, 
            c.ItemDescription, 
            b.Description, 
            c.Navigation + '.' + b.LineOrder, 
            b.Qty, 
            b.BIMUnique
        from cte c
        inner join BidItems b on b.SuperiorUnique = c.BIMUnique
    )
    select * from cte
    

    Demo on SQL Server 2012

    顶层描述 |直属父母 |物品描述 |导航 |数量 | BIM独特 :---------------------------- | :-------------------------------------------------------- | :-------------------------------------------------------- | :--------- | --: | --------: 顶级订单说明 | 0 |顶级订单说明 | 1 | 1 | 660084 顶级订单说明 |顶级订单说明 |二级订单说明 | 1.1 | 50 | 660085 顶级订单说明 |顶级订单说明 |二级订单描述 w/sub order | 1.2 | 200 | 660086 顶级订单说明 |二级订单描述 w/sub order |三级订单说明 | 1.2.7 | 10 | 660087

    【讨论】:

    • 我收到这两个错误。我现在假设它是某种数据类型不匹配?递归查询“cte”的“ImmediateParent”列中的锚点和递归部分之间的类型不匹配。递归查询“cte”的“导航”列中的锚点和递归部分的类型不匹配。
    • @user2962869:您可能需要一些转换... ItemDescriptionLineOrder 列的数据类型是什么?
    • BIMUnique 是 int,LineOrder 是 varchar(12),Description 是 varchar(60),SuperiorUnique 是 int。我已经尝试过 CONVERT(varchar(10), bi.Navigation) + CONVERT(varchar(10), m.LineCode) ,但我仍然得到错误。
    • @user2962869:我稍微修改了查询。请再试一次。
    • 我得到同样的错误 - 递归查询“cte”的“ImmediateParent”列中的锚点和递归部分之间的类型不匹配,并且锚点和递归部分之间的类型不匹配在递归查询“cte”的“导航”列中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 2014-10-18
    • 2018-03-30
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多