Reputation: 13
I want to create a view that splits a row based on the number in the cell "QTY"
Row 1 has value 1 in cell "QTY" and should result in 1 row
Row 2 has value 2 in cell "QTY" and should result in 2 rows
Row 3 has value 4 in cell "QTY" and should result in 4 rows
My table
QTY ITEM
1 | aaa
2 | bbb
4 | ccc
My result should look like this
QTY ITEM
1 | aaa
2 | bbb
2 | bbb
4 | ccc
4 | ccc
4 | ccc
4 | ccc
Create table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[mytable](
[QTY] [int] NULL,
[Item] [nchar](10) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[mytable] ([QTY], [Item]) VALUES (1, N'aaa ')
GO
INSERT [dbo].[mytable] ([QTY], [Item]) VALUES (2, N'bbb ')
GO
INSERT [dbo].[mytable] ([QTY], [Item]) VALUES (4, N'ccc ')
GO
Upvotes: 1
Views: 371
Reputation: 5653
You can try this solution also using the master.dbo.spt_values
.
create table MyTable (QTY int, ITEM varchar(10))
insert into MyTable Values
(1, 'aaa'),
(2, 'bbb'),
(4, 'ccc')
SELECT t1.*, t2.number + 1 RepeatNumber
FROM MyTable t1
JOIN master.dbo.spt_values t2 ON t2.type = 'P' AND t2.number < t1.QTY
Here is the demo at: db<>fiddle
Upvotes: 0
Reputation: 96028
I would use a Tally to do this, and then JOIN
on No
being greater or equal to the value in the Tally:
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP(SELECT MAX([No]) FROM dbo.mytable) --if 185 isn't to change, then I would replace the sub query with 185
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3) --216 rows, add more Ns here, or more NULLs above to make larger
SELECT mt.[No] AS QTY,
mt.Item
FROM dbo.mytable mt
JOIN Tally T ON mt.[No] >= T.I;
Upvotes: 0
Reputation: 14928
You could do as:
SELECT T.*
FROM
(
VALUES
(1, 'aaa'),
(2, 'bbb'),
(4, 'ccc')
) T(Qty, Item) CROSS APPLY
(
SELECT Number
FROM Master..SPT_VALUES
WHERE TYPE = 'P' AND Number > 0 AND Number <= T.Qty
) TT(N)
Note: You can replace master..spt_values
with a tally table.
Upvotes: 1