我有一个包含产品信息和数量列的测试表。
ProdID = 1 Qty = 3
在“数量”大于1的情况下,我需要为“数量”生成额外的行,这样输出的行数将永远只有“数量” = 1:
ProdID = 1 Qty = 1
ProdID = 1 Qty = 1
ProdID = 1 Qty = 1
我有点困惑,从哪里开始,我曾经考虑过尝试添加一行然后每次减少数量,但这会循环,如何通过Set操作来完成...递归cte,交叉申请,可以在tsql中完成吗?
with cte_test
as
(select a.* from
(values('01-JAN-19','PROD1','BLUE',10.00, 1)
,('01-JAN-19','PROD1','RED',10.00, 1)
,('02-JAN-19','PROD1','BLUE',10.00, 2)
,('02-JAN-19','PROD2','BLUE',10.00, 1)
,('03-JAN-19','PROD1','RED',20.00, 6)
,('04-JAN-19','PROD1','BLUE',10.00, 1)
,('04-JAN-19','PROD3','BLACK',10.00, 3)
,('05-JAN-19','PROD1','BLUE',10.00, 2)
) as a ([Date],[Product],[Colour],[Price],[Qty])
)
select [Date],[Product],[Colour],[Price],[Qty]
from cte_test
答案 0 :(得分:1)
为此,我喜欢递归CTE:
with cte as (
select [Date], [Product], [Colour], [Price], [Qty]
from [TestTable]
union all
select [Date], [Product], [Colour], [Price], [Qty] - 1
from cte
where Qty > 1
)
select [Date], [Product], [Colour], [Price], 1 as [Qty]
from cte;
如果Qty
大于100,则需要添加option (maxrecursive 0)
。
答案 1 :(得分:1)
使用递归CTE:
declare @maxqty int = (select max(qty) from [TestTable]);
with cte AS (
select 1 qty
union all
select qty + 1 from cte where qty + 1 <= @maxqty
)
select [Date], [Product], [Colour], [Price], 1 as [Qty]
from [TestTable] t inner join cte c
on c.qty <= t.qty
order by [Date], [Product]
请参见demo。
结果:
> Date | Product | Colour | Price | Qty
> :-------- | :------ | :----- | :---- | --:
> 01-JAN-19 | PROD1 | BLUE | 10.00 | 1
> 01-JAN-19 | PROD1 | RED | 10.00 | 1
> 02-JAN-19 | PROD1 | BLUE | 10.00 | 1
> 02-JAN-19 | PROD1 | BLUE | 10.00 | 1
> 02-JAN-19 | PROD2 | BLUE | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 03-JAN-19 | PROD1 | RED | 10.00 | 1
> 04-JAN-19 | PROD1 | BLUE | 10.00 | 1
> 04-JAN-19 | PROD3 | BLACK | 10.00 | 1
> 04-JAN-19 | PROD3 | BLACK | 10.00 | 1
> 04-JAN-19 | PROD3 | BLACK | 10.00 | 1
> 05-JAN-19 | PROD1 | BLUE | 10.00 | 1
> 05-JAN-19 | PROD1 | BLUE | 10.00 | 1