【问题标题】:Repeating rows based on count in a different column - SQL根据不同列中的计数重复行 - SQL
【发布时间】:2019-01-28 23:42:44
【问题描述】:

我有一个包含 ID 和计数的表。我想重复计数中提到的次数。

我的桌子:

期望的输出:

我的代码:

    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

我的代码缺少一些无法产生预期结果的内容。有什么帮助吗?!

【问题讨论】:

标签: sql sql-server


【解决方案1】:

您需要一个达到 count 列最大值的数字表,然后可以使用它来生成多行。这个数字生成可以使用递归 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

【讨论】:

    【解决方案2】:

    另一种选择是临时计数表

    示例

    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]
    

    退货

    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
    

    【讨论】:

      【解决方案3】:

      我会使用递归 CTE,但直接:

      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;
      

      如果您的计数超过 100,那么您需要使用 option (maxrecursion 0)

      【讨论】:

        【解决方案4】:

        感谢大家的建议。我使用以下查询来解决我的问题:

        ;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
        

        【讨论】:

          猜你喜欢
          • 2018-02-13
          • 1970-01-01
          • 1970-01-01
          • 2016-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-29
          相关资源
          最近更新 更多