Как создать повторяющиеся записи в зависимости от столбца, который указывает на повторение - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть таблица, которая состоит из агрегированных записей, и мне нужно разделить их по определенному столбцу («Купленные акции», как в примере ниже), как показано ниже:

Исходная таблица:

enter image description here

Запрошенная таблица:

enter image description here

Само собой разумеется, что естьв таблице больше таких записей, и мне нужен автоматический запрос (не вставка вручную), а также есть еще несколько атрибутов, которые мне нужно будет дублировать (например, поле «Дата»).

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018
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 nums или добавьте туда столько значений, сколько вы можете найти в столбце «Купленные акции».

0 голосов
/ 12 декабря 2018

Другой вариант - использовать 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.

0 голосов
/ 12 декабря 2018

Сначала вам нужно будет сгенерировать row_number с увеличивающимся номером строки, а затем выполнить перекрестное соединение со своей таблицей.

Например:

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

...