我有一个包含汇总记录的表,我需要根据特定列(如以下示例中的“购买的股份”)对它们进行拆分,如下所示:
原始表:
请求的表:
不用说,表中还有更多类似的记录,而我需要一个自动查询(而不是手动插入), 并且还有一些我需要重复的属性(例如“日期”字段)。
答案 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
。