如何根据表示重复的列创建重复记录

时间:2018-12-12 07:18:10

标签: sql sql-server duplicates

我有一个包含汇总记录的表,我需要根据特定列(如以下示例中的“购买的​​股份”)对它们进行拆分,如下所示:

原始表:

binding context

请求的表:

enter image description here

不用说,表中还有更多类似的记录,而我需要一个自动查询(而不是手动插入), 并且还有一些我需要重复的属性(例如“日期”字段)。

3 个答案:

答案 0 :(得分:2)

您首先需要使用row_number增加的generate_rows,然后对表执行交叉联接。

例如:

create table t(rowid int, name varchar(100),shares_bought int, date_val date)

insert into t
select *
from (values (1,'Dan',2,'2018-08-23')
            ,(2,'Mirko',1,'2018-08-25')
            ,(3,'Shuli',3,'2018-05-14')
            ,(4,'Regina',1,'2018-01-19')
            )t(x,y,z,a)

with generate_data
  as (select top (select max(shares_bought) from t)
             row_number() over(order by (select null)) as rnk /* This would generate rows starting from 1,2,3 etc*/
       from sys.objects a
       cross join sys.objects b
   )
select row_number() over(order by t.rowid) as rowid,t.name,1 as shares_bought,t.date_val
  from t 
  join generate_data gd
    on gd.rnk <=t.shares_bought /* generate rows up and until the number of shares bought*/
 order by 1

这是一个分贝小提琴链接

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=5736255585c3ab2c2964c655bec9e08b

答案 1 :(得分:1)

declare @t table (rowid int, name varchar(100), sb int, dt date);
insert into @t values
(1, 'Dan', 2, '20180823'),
(2, 'Mirco', 1, '20180825'),
(3, 'Shuli', 3, '20180514'),
(4, 'Regina', 1, '20180119');

with nums as
(
select n
from (values(1), (2), (3), (4)) v(n)
)

select t.*
from @t t
     cross apply (select top (t.sb) *
                  from nums) a;

使用数字而不是CTE的数字表,或在其中添加尽可能多的值(在“购买的股份”列中可以找到)。

答案 2 :(得分:0)

其他选择是使用recursive cte:

with t as (
     select 1 as RowId, Name, ShareBought, Date
     from table
     union all
     select RowId+1, Name, ShareBought, Date
     from t
     where RowId <= ShareBought
)
select row_number() over (order by name) as RowId, 
       Name, 1 as ShareBought, Date 
from t;

如果购买的份额不仅仅限于2或3,则您将不得不使用option (maxrecursion 0)查询提示,因为默认情况下它仅限于100 sharebought