2016-10-08 3 views
1

아래와 같은 표가 있는데, 기간 열로 분할하려고합니다. 아래 예제에서 60 행이지만 각 분 간격으로 나타납니다. 시간이 1 분 증가한다는 의미입니다.SQL 서버

Filmtitle     startTime     duration 
---------------------------------------------------------------- 
WW2's most daring raids  2016-10-03 00:00:00.000  60 

원하는 결과 :

WW2's most daring raids  2016-10-03 00:00:01.000  60 
WW2's most daring raids  2016-10-03 00:00:02.000  60 
... 
WW2's most daring raids  2016-10-03 00:00:59.000  60 

어떤 아이디어?

미리 감사드립니다.

답변

0

도움이 될만한 TVF가 있습니다. 동적 날짜 범위를 만드는 데 사용됩니다. Tally/Numbers 테이블도 트릭을 수행합니다.

Declare @YourTable table (Filmtitle varchar(100),startTime datetime,duration int) 
Insert Into @YourTable values 
('WW2''s most daring raids','2016-10-03 00:00:00.000',60) 

Select A.Filmtitle 
     ,SomeName=B.RetVal 
     ,A.duration 
From @YourTable A 
Cross Apply [dbo].[udf-Range-Date](A.startTime,DateAdd(MI,A.Duration-1,A.startTime),'MI',1) B 

반환

Filmtitle    SomeName    duration 
WW2's most daring raids 2016-10-03 00:00:00.000 60 
WW2's most daring raids 2016-10-03 00:01:00.000 60 
WW2's most daring raids 2016-10-03 00:02:00.000 60 
--- 
WW2's most daring raids 2016-10-03 00:57:00.000 60 
WW2's most daring raids 2016-10-03 00:58:00.000 60 
WW2's most daring raids 2016-10-03 00:59:00.000 60 

다른 옵션 UDF를 원하지 않는 경우

CREATE FUNCTION [dbo].[udf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int) 
Returns Table 
Return (
    with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End), 
     cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), 
     cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h), 
     cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2) 

    Select RetSeq = N+1 
      ,RetVal = D 
    From cte3,cte0 
    Where D<[email protected] 
) 
/* 
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS 
Syntax: 
Select * from [dbo].[udf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[udf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
*/ 
0

를 필요한 경우이 함수는 임시 집계 테이블

Declare @YourTable table (Filmtitle varchar(100),startTime datetime,duration int) 
Insert Into @YourTable values 
('WW2''s most daring raids','2016-10-03 00:00:00.000',60) 

Select A.Filmtitle 
     ,SomeName=DateAdd(MI,RN,startTime) 
     ,A.duration 
From @YourTable A 
Join (
     Select RN=Row_Number() over (Order By (Select Null)) 
     From (Select N=1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)) A 
     Join (Select N=1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)) B on 1=1 
     ) B on 1=1 
Where B.RN<A.duration 

에게 있습니다

을 반환합니다.
Filmtitle    SomeName    duration 
WW2's most daring raids 2016-10-03 00:00:00.000 60 
WW2's most daring raids 2016-10-03 00:01:00.000 60 
WW2's most daring raids 2016-10-03 00:02:00.000 60 
--- 
WW2's most daring raids 2016-10-03 00:57:00.000 60 
WW2's most daring raids 2016-10-03 00:58:00.000 60 
WW2's most daring raids 2016-10-03 00:59:00.000 60 
+0

감사합니다. 존, 처음에는 잘 이해하지 못했지만, 두 번째 대답은 그럴 뻔했으나 시간이 중복되었습니다. 어떤 아이디어? –

+0

@eddieB 허, Distinct A.Filmtitle을 선택하십시오 ... 주머니에 UDF를 보관하십시오. 나는 그것으로부터 엄청난 사용량을 얻는다. –

+0

죄송합니다. 신경 쓰지 마세요, 실제로 연습을 위해 중복 된 행이 있다는 것을 깨달았습니다 :) 이것에 대해 많은 감사를드립니다 !! –

0

시도해 볼 수도 있습니다. 아이디어는 기간을 1에서 Duration -1까지 번호가 매겨진 동일한 수의 행으로 변환하는 것입니다. row_number를 시작 날짜에 추가하십시오.

declare @table table(Film varchar(50), StartDate datetime, duration int) 
insert into @table values 
('WW2''s most daring raids', '2016-10-03 00:00:00.000', 60) 


;with cte as(
    select Film, StartDate, cast(Replicate('<k>1</k>', Duration-1) as xml) as x 
    from @table 
) 
, cte2 as(
    select Film, startdate, 
    ROW_NUMBER() over(partition by Film, StartDate order by (select null)) as RN 
    from cte 
    outer apply x.nodes('/k') t(Dur) 
) 
select Film, Startdate, dateadd(second, RN, StartDate) as EndDate 
from cte2 as a 
+0

고마워 아메드, 작동하는 것 같지만, 나를 위해 너무 진보 된 방법을 이해할 수 없습니다 :) –

+0

사실, cte는 File과 StartDate 이외에 새로운 XML 열에 '' . cte2는 ROW_NUMBER 함수에 의해 1에서 59까지 번호가 매겨진 행으로 변환하도록 OUTER에 적용합니다. 그런 다음 마지막 SELECT에서이 행 번호를 StartDate에 추가하여 필요한 결과를 얻으십시오. –