简体   繁体   中英

Repeating rows based on count in a different column - SQL

I have a table that holds IDs and count. I want to repeat the rows the number of times mentioned in the count.

My table:

在此处输入图片说明

Desired output:

在此处输入图片说明

My code:

    create table #temp1(CID int, CVID int, count int)
    insert #temp1
    values
    (9906,  4687,   4),
    (9906,  4693,   5)

    create table #temp2 (CID int,CVID int, count int,ro int)

    ;with t3 as (
    select c.CID,c.CVID, c.count, row_number() over (partition by c.CID order by c.CID) ro 
    from #temp1 c
    )
    insert #temp2 
    select CID,CVID,count,ro from t3 where ro <= count

My code is missing something that its not producing desired result. Any help?!

You need a numbers table up to the maximum value of count column which can then be used to generate multiple rows. This number generation can be done using a recursive cte.

--Recursive CTE
with nums(n) as (select max(count) from #temp1
                 union all
                 select n-1 
                 from nums 
                 where n > 1
                )
--Query to generate multiple rows
select t.*,nums.n as ro
from #temp1 t
join nums on nums.n <= t.count

Just another option is an ad-hoc tally table

Example

Select A.*
      ,Ro = B.N
 From  YourTable A 
 Join  ( Select Top 1000 N=Row_Number() Over (Order By (Select NULL)) 
          From  master..spt_values n1 ) B on B.N<=A.[Count]

Returns

CID     CVID    COUNT   Ro
9906    4687    4       1
9906    4687    4       2
9906    4687    4       3
9906    4687    4       4
9906    4693    5       1
9906    4693    5       2
9906    4693    5       3
9906    4693    5       4
9906    4693    5       5

I would use a recursive CTE, but directly:

with cte as (
      select CID, CVID, count, 1 as ro
      from #temp1
      union all
      select CID, CVID, count, ro + 1
      from cte
      where cte.ro < cte.count
     )
select cte.*
from cte;

If your counts exceed 100, then you'll need to use option (maxrecursion 0) .

Thanks all for all the suggestion. I used the below query to solve my problem:

;with    cte(cid, cvid,count, i) as 
        (
        select  cid
        ,       cvid
        ,       count
        ,       1
        from    #temp1
        union all
        select  cid
        ,       cvid
        ,       count
        ,       i + 1
        from    cte
        where   cte.i < cte.count
        )
select  *
from    cte
order by
        cid,count

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM