我有一个问题 如果我有一行看起来像这样
|ordernumber|qty|articlenumber| | 123125213| 3 |fffff111 |
如何将其拆分为三行,如下所示:
|ordernumber|qty|articlenumber| | 123125213| 1 |fffff111 | | 123125213| 1 |fffff111 | | 123125213| 1 |fffff111 |
/ J
答案 0 :(得分:5)
您可以使用递归CTE:
WITH RCTE AS
(
SELECT
ordernumber, qty, articlenumber, qty AS L
FROM Table1
UNION ALL
SELECT
ordernumber, 1, articlenumber, L - 1 AS L
FROM RCTE
WHERE L>0
)
SELECT ordernumber,qty, articlenumber
FROM RCTE WHERE qty = 1
<强> SQLFiddleDEMO 强>
修改强> 根据Marek Grzenkowicz的回答和MatBailie的评论,全新的想法:
WITH CTE_Nums AS
(
SELECT MAX(qty) n FROM dbo.Table1
UNION ALL
SELECT n-1 FROM CTE_Nums
WHERE n>1
)
SELECT ordernumber ,
1 AS qty,
articlenumber
FROM dbo.Table1 t1
INNER JOIN CTE_Nums n ON t1.qty >= n.n
生成从1到最大(数量)的数字并在其上连接表。
<强> SQLFiddle DEMO 强>
答案 1 :(得分:2)
这是一个快速入侵,使用一个附加表,其中填充了适合您期望的qty
值的行数:
-- helper table
CREATE TABLE qty_splitter (qty int)
INSERT INTO qty_splitter VALUES (1)
INSERT INTO qty_splitter VALUES (2)
INSERT INTO qty_splitter VALUES (3)
INSERT INTO qty_splitter VALUES (4)
INSERT INTO qty_splitter VALUES (5)
....
-- query to produce split rows
SELECT t1.ordernumber, 1, t1.articlenumber
FROM table1 t1
INNER JOIN qty_splitter qs on t.qty >= qs.qty
答案 2 :(得分:1)
您可以使用CTE
执行此操作declare @t table (ordername varchar(50), qty int)
insert into @t values ('ord1',5),('ord2',3)
;with cte as
(
select ordername, qty, qty-1 n
from @t
union all
select ordername, qty, n-1
from cte
where n>0
)
select ordername,1
from cte
order by ordername
答案 3 :(得分:1)
您还可以在master..spt_values系统表中使用选项。
SELECT t.ordernumber, o.qty, t.articlenumber
FROM dbo.SplitTable t CROSS APPLY (
SELECT 1 AS qty
FROM master..spt_values v
WHERE v.TYPE = 'P' AND v.number < t.qty
) o
但是,为此目的,最好使用自己的序列表
请参阅SQLFiddle