Генерация строк в таблице на основе существующих строк - PullRequest
0 голосов
/ 25 марта 2020

Можно ли генерировать строки в таблице на основе существующего столбца в таблице на SQL Сервере? Например, если RunDates value = 31/01/2020 и RunTimes = 3, то в таблице должно быть 3 строки для RunDate = 31/01/2020

Текущая таблица

Current Table

Желаемая таблица

Desired table

Ответы [ 3 ]

2 голосов
/ 25 марта 2020

Вы можете сделать это с помощью рекурсивного CTE:

with cte as (
  select RunDates, RunTimes, 1 nr from tablename
  union all
  select RunDates, RunTimes, nr + 1 
  from cte
  where nr < RunTimes
)
select RunDates, RunTimes from cte
order by RunDates

См. Демоверсию . Результаты:

> RunDates   | RunTimes
> :--------- | -------:
> 2020-01-31 |        3
> 2020-01-31 |        3
> 2020-01-31 |        3
> 2020-02-29 |        2
> 2020-02-29 |        2
> 2020-03-31 |        1
1 голос
/ 25 марта 2020

Сначала вам нужен подсчет (например)

CREATE View [dbo].[cteTally]
as
WITH
  E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n))
  , E2(N) AS (SELECT 1 FROM E1 a, E1 b) --10E+2 or 100 rows
  , E4(N) AS (SELECT 1 FROM E2 a, E2 b) --10E+4 or 10,000 rows max
  , cteTally(N) AS (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
  )
select N from cteTally
GO

Затем вы присоединяете его к вашему столу, например

declare @MyTable table (MyDate date, RunCount int);

insert into @MyTable (MyDate, RunCount)
  values
  ('31 Jan 2020', 3),
  ('29 Feb 2020', 2),
  ('31 Mar 2020', 1);

select MT.*
from @MyTable MT
inner join cteTally T on T.N <= MT.RunCount
order by MyDate, RunCount;

Возвращает:

MyDate      RunCount
--------------------
2020-01-31  3
2020-01-31  3
2020-01-31  3
2020-02-29  2
2020-02-29  2
2020-03-31  1

ПРИМЕЧАНИЕ: Tally Table любезно предоставлен @Larnu, но я не могу найти оригинальный пост.

0 голосов
/ 25 марта 2020

Вы можете попробовать следующее внутреннее соединение, создав серийный номер из sys.objects.

Здесь я зафиксировал 10, предполагая максимальное значение RunTime. Вы можете создать переменную и присвоить значение maximum значения RunTime и использовать эту переменную вместо 10.

. Здесь есть другой способ для этого.

create table SampleTable (DtDate Date, RunTimes int)
insert into SampleTable Values
('31 Jan 2020', 3),
('29 Feb 2020', 2),
('31 Mar 2020', 1)

SELECT SampleTable.*
FROM SampleTable
INNER JOIN (
    SELECT TOP 10 ROW_NUMBER() OVER (
            ORDER BY object_id
            ) AS SrNo
    FROM sys.objects
    ) mst ON RunTimes >= SrNo
ORDER BY DtDate

Live db <> fiddle demo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...