2

I am trying to create a query from my database which will expand each row to multiple rows based on a count column. What I need is to take my table:

[DATE]     [COUNT]     [OTHER_COLUMN]
20120101   3           X
20120201   2           Y

And create this:

[DATE]     [OTHER_COLUMN]
20120101   X
20120101   X
20120101   X
20120201   Y
20120201   Y

I have found lots of ways to do the opposite (merge multiple rows into one), or to expand one row with multiple columns into multiple rows (one based on each column), but I can't seem to find a way to create identical rows. I am using SQL Server 2012.

3 Answers 3

4

You can use a recursive CTE:

;WITH CTE AS
(
    SELECT *, 1 RN
    FROM YourTable
    UNION ALL
    SELECT [DATE], [COUNT], [OTHER_COLUMN], RN+1
    FROM CTE
    WHERE RN+1 <= [COUNT]
)
SELECT [DATE], [OTHER_COLUMN]
FROM CTE
OPTION(MAXRECURSION 0)

And here is a sql fiddle for you to try.

Sign up to request clarification or add additional context in comments.

5 Comments

@bluefeet Thanks, added a fiddle now
This is causing the table to get scanned once per recursion step. If the table grows or the counts grow this is going to be very slow.
@SebastianMeine It doesn't necessarily scan the table once per recursion, actually. In the fiddle in question, the query scan the table once. Though, this doesn't mean necessarily that its not gonna be slow either
I just ran your version with STATISTICS IO on. The output shows 1 logical read on the table and 29 logical reads on a worktable. So yes, you are right that the table gets scanned only once, however the total is still 30 logical reads. My solution gets away with one logical read.
@SebastianMeine That's great, actually. This is just one alternative to the problem asked. I'm in no way over defending my answer nor criticizing yours.
2

For this you need a tally table like this one: http://www.sqlmag.com/article/sql-server/virtual-auxiliary-table-of-numbers

Then you can just write:

SELECT [Date], Other_Column
FROM dbo.MyTable
CROSS APPLY dbo.GetNums([COUNT]);

Here is a SQL-Fiddle to show the solution in action: http://sqlfiddle.com/#!6/2edda/2

Comments

0

Another way to do it. Please note that you should have [count] <=2048. Otherwise, build another number table as you need.

WITH num AS (
    SELECT number
    FROM master..spt_values WHERE type = 'P' 
)
SELECT 
    [DATE],[OTHER_COLUMN]
FROM your_table t
INNER JOIN num n
    ON n.number < t.COUNT 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.