递归 CTE 以获得顶级结果
Recursive CTE to get top level results
这是我当前的数据集。
| 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。
考虑以下查询,它从根到叶遍历树。我真的不认为 row_number()
需要生成路径,这显然是由 LineNumber
s.
组成的
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
TopLevelDescription | ImmediateParent | ItemDescription | Navigation | Qty | BIMUnique
:-------------------------- | :----------------------------------------- | :----------------------------------------- | :--------- | --: | --------:
Top Level Order Description | 0 | Top Level Order Description | 1 | 1 | 660084
Top Level Order Description | Top Level Order Description | Second Level Order Description | 1.1 | 50 | 660085
Top Level Order Description | Top Level Order Description | Second Level Order Description w/sub order | 1.2 | 200 | 660086
Top Level Order Description | Second Level Order Description w/sub order | Third Level Order Description | 1.2.7 | 10 | 660087
这是我当前的数据集。
| 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。
考虑以下查询,它从根到叶遍历树。我真的不认为 row_number()
需要生成路径,这显然是由 LineNumber
s.
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
TopLevelDescription | ImmediateParent | ItemDescription | Navigation | Qty | BIMUnique :-------------------------- | :----------------------------------------- | :----------------------------------------- | :--------- | --: | --------: Top Level Order Description | 0 | Top Level Order Description | 1 | 1 | 660084 Top Level Order Description | Top Level Order Description | Second Level Order Description | 1.1 | 50 | 660085 Top Level Order Description | Top Level Order Description | Second Level Order Description w/sub order | 1.2 | 200 | 660086 Top Level Order Description | Second Level Order Description w/sub order | Third Level Order Description | 1.2.7 | 10 | 660087