基于列值拆分行的递归 CTE
Recursive CTE to split rows based on a column value
我有一个 CTE returns 一组项目 ID 和数量。我正在尝试使用另一个 CTE 根据定义的容器大小将每一行拆分为多行。例如,如果容器大小指定为 20,行数为 49,我想将其拆分为 2 行 20 行和 1 行 9。
下面是我最终卡住的地方。对于这种情况,递归 CTE 是错误的选择吗?任何帮助将不胜感激。
DECLARE @ContainerSize int = 20;
WITH ItemDetails (ItemID, Qty) AS (
-- Query that returns data like below
SELECT 29, 49
UNION ALL
SELECT 33, 64
UNION ALL
SELECT 38, 32
UNION ALL
SELECT 41, 54
),
ItemDetailsSplit(n, ItemID, Qty) AS (
SELECT
0,
ItemID,
Qty
FROM ItemDetails
UNION ALL
SELECT
n + 1,
ItemID,
CASE WHEN Qty < (@ContainerSize * (n + 1))
THEN Qty
ELSE Qty - (@ContainerSize * (n + 1))
END AS [Qty]
FROM ItemDetailsSplit
WHERE ( Qty > (@ContainerSize * n) )
)
SELECT *
FROM ItemDetailsSplit
ORDER BY ItemID, Qty DESC;
在不知道您的特定 RDBMS 的情况下,我有一个适用于 SQL 服务器的解决方案,它可以轻松转换table 到任何数据库平台。
这使用 数字 table - 这里是另一个 CTE,但在生产中你会有一个永久的 table.
declare @ContainerSize int = 20;
with numbers (n) as (
select top(100) Row_Number() over(order by(select null)) from master.dbo.spt_values
), ItemDetails (ItemID, Qty) as (
-- Query that returns data like below
select 29, 49
union all
select 33, 64
union all
select 38, 32
union all
select 41, 54
)
select ItemID, Iif(n <= Qty / @ContainerSize, @ContainerSize, Qty % @ContainerSize) Qty
from ItemDetails d
cross apply numbers n
where n <= (Qty / @ContainerSize) + Iif(Qty % @ContainerSize = 0, 0, 1)
order by ItemID, Qty
我有一个 CTE returns 一组项目 ID 和数量。我正在尝试使用另一个 CTE 根据定义的容器大小将每一行拆分为多行。例如,如果容器大小指定为 20,行数为 49,我想将其拆分为 2 行 20 行和 1 行 9。
下面是我最终卡住的地方。对于这种情况,递归 CTE 是错误的选择吗?任何帮助将不胜感激。
DECLARE @ContainerSize int = 20;
WITH ItemDetails (ItemID, Qty) AS (
-- Query that returns data like below
SELECT 29, 49
UNION ALL
SELECT 33, 64
UNION ALL
SELECT 38, 32
UNION ALL
SELECT 41, 54
),
ItemDetailsSplit(n, ItemID, Qty) AS (
SELECT
0,
ItemID,
Qty
FROM ItemDetails
UNION ALL
SELECT
n + 1,
ItemID,
CASE WHEN Qty < (@ContainerSize * (n + 1))
THEN Qty
ELSE Qty - (@ContainerSize * (n + 1))
END AS [Qty]
FROM ItemDetailsSplit
WHERE ( Qty > (@ContainerSize * n) )
)
SELECT *
FROM ItemDetailsSplit
ORDER BY ItemID, Qty DESC;
在不知道您的特定 RDBMS 的情况下,我有一个适用于 SQL 服务器的解决方案,它可以轻松转换table 到任何数据库平台。
这使用 数字 table - 这里是另一个 CTE,但在生产中你会有一个永久的 table.
declare @ContainerSize int = 20;
with numbers (n) as (
select top(100) Row_Number() over(order by(select null)) from master.dbo.spt_values
), ItemDetails (ItemID, Qty) as (
-- Query that returns data like below
select 29, 49
union all
select 33, 64
union all
select 38, 32
union all
select 41, 54
)
select ItemID, Iif(n <= Qty / @ContainerSize, @ContainerSize, Qty % @ContainerSize) Qty
from ItemDetails d
cross apply numbers n
where n <= (Qty / @ContainerSize) + Iif(Qty % @ContainerSize = 0, 0, 1)
order by ItemID, Qty