2013-05-15 3 views
2

에서 여러 행을 만들기 테이블 구조 티켓 오픈 시간과 티켓 마감 시간이 거짓 인 경우내가 가진 단일 행 SQL

ATM   Ticket Open Time Ticket Closed Time 

M30G324202 17-02-2013 06:15 19-02-2013 20:54 
M30G324202 28-02-2013 21:00 01-03-2013 11:18 
M30G324203 27-02-2013 19:10 28-02-2013 07:14 
M30G324203 28-02-2013 07:15 28-02-2013 11:18 

'20과 같은 : 00 : 00 '과 '06 : 00 : 00'즉, (8) PM & 오전 6시 해당 시간대가없는 새 행을 만들어야합니다.

예 : 상기 표

ATM   Ticket Open Time Ticket Closed Time 

M30G324202 17-02-2013 06:15 17-02-2013 20:00 
M30G324202 18-02-2013 06:00 18-02-2013 20:00 
M30G324202 19-02-2013 06:00 19-02-2013 20:00 

//Above was for Only 1st Row 

//Second Row Change AS Follows 

M30G324202 01-03-2013 06:00 01-03-2013 11:18 
    (Time From 28-02-2013 21:00 Will get neglected till next day morning 6 AM 
    as it is after 8 PM) 

//Third Row Change AS Follows 

M30G324203 27-02-2013 19:10 27-02-2013 20:00 
M30G324203 28-02-2013 06:00 28-02-2013 07:14 

//Fourth Row Change AS Follows 

M30G324203 28-02-2013 07:15 28-02-2013 11:18 (No Change as it is) 

에서 첫번째 행 I는 20:00 대신 20:54 54 분 때문에 작성했다. 오후 9시에 오후 8시 이후입니다.

+0

그래서, 단지 명확하게하기를, 당신이있어 데이터의 모든 행에 대해 그 범위에 속하는 각 날짜에 대해 별도의 행을 선택한 후? – KaraokeStu

+0

Absolutely Correct .. !!! !!! – Shaggy

+2

두 번째 항목'M30G324202'에도 예상되는 결과를 추가하십시오. – TechDo

답변

1

대단한 질문입니다. 내 시도 확인하시기 바랍니다 :

declare @tbl as table (ATM nvarchar(20), TicketOpenTime datetime, TicketClosedTime datetime) 
insert into @tbl values 
('M30G324202', '02-17-2013 06:15', '02-19-2013 20:54'), 
('M30G324202', '02-28-2013 21:00', '03-01-2013 11:18'), 
('M30G324203', '02-27-2013 19:10', '02-28-2013 07:14'), 
('M30G324203', '02-28-2013 07:15', '02-28-2013 11:18') 

declare @min datetime, @max datetime 
select @min = MIN(TicketOpenTime), @max = max(TicketClosedTime) from @tbl 

;with T as(
    select CONVERT(datetime, convert(numeric(20), @min, 101)) dt 
    union all 
    select dt+1 from T where dt<@max 
) 
select 
    a.ATM, 
    case when a.TicketOpenTime>dt1 then a.TicketOpenTime else dt1 end TicketOpenTime, 
    case when a.TicketClosedTime>dt2 then dt2 else a.TicketClosedTime end TicketClosedTime 
From @tbl a 
cross apply(
    select 
     dt, 
     DATEADD(minute, 360, dt) dt1, 
     DATEADD(minute, 1200, dt) dt2 from T b 
    where 
     dt between CAST(a.TicketOpenTime as DATE) and cast(a.TicketClosedTime as DATE) 
)x 
where a.TicketOpenTime<=x.dt2 
order by a.ATM, a. TicketOpenTime 
+0

수정 된 답변을 확인하십시오. – TechDo

2

재귀 CTE를 사용하여이 작업을 수행 할 수 있습니다. 다음 코드는 방법을 보여줍니다. CTE A에서 테스트 데이터의 경우, 모든 경우는 처리를 촬영 한 것을 보여주기 위해

SELECT ATM, [Ticket Open Time], [Ticket Close Time] FROM Table1 

테스트 데이터가 여기에 같은 것을 사용합니다. case ATM = W를 포함시키지 않거나 시작 날짜를 조정하려는 경우, 그에 따라 SQL을 수정할 수 있습니다.

또한 구식 기술을 사용하여 datetime의 날짜 부분을 가져 왔습니다. 다시 SQL Server 버전에 따라 조정하십시오.

WITH A 
AS (

    SELECT 'X' as ATM 
     , convert(datetime, '2/17/2013 6:15') as [Ticket Open Time] 
     , convert(datetime, '2/19/2013 20:54') as [Ticket Close Time] 
    UNION ALL 
    SELECT 'Y' 
     , convert(datetime, '2/24/2013 7:32') 
     , convert(datetime, '2/25/2013 14:26') 
    UNION ALL 
    SELECT 'Z' 
     , convert(datetime, '2/20/2013 9:00') 
     , convert(datetime, '2/20/2013 13:43')  
    UNION ALL 
    SELECT 'W' 
     , convert(datetime, '3/1/2013 3:34') 
     , convert(datetime, '3/1/2013 6:45') 
) 
, B 
AS (

    SELECT ATM 
     , [Ticket Open Time] 
     , [Original Ticket Close Time] = A.[Ticket Close Time] 
     , [Ticket Close Time] = CASE WHEN DateAdd(hh, 20, convert(datetime, convert(varchar(10), [Ticket Open Time], 101))) > A.[Ticket Close Time] 
       THEN [Ticket Close Time] 
       ELSE DateAdd(hh, 20, convert(datetime, convert(varchar(10), [Ticket Open Time], 101))) 
      END 
    FROM A 
    UNION ALL 
    SELECT ATM 
     , [Ticket Open Time] = DateAdd(hh, 10, B1.[Ticket Close Time]) 
     , [Original Ticket Close Time] = b1.[Original Ticket Close Time] 
     , [Ticket Close Time] = CASE 
       WHEN DateAdd(hh, 24, b1.[Ticket Close Time]) > b1.[Original Ticket Close Time] 
       AND b1.[Original Ticket Close Time] <= DateAdd(hh,24, b1.[Ticket Close Time]) 
       THEN b1.[Original Ticket Close Time] 
       ELSE DateAdd(hh, 24, b1.[Ticket Close Time]) 
      END 
    FROM B b1 
    WHERE [Ticket Close Time] < b1.[Original Ticket Close Time] 

) 
, C 
as (
    select * 
    from B 
    where [Ticket Open Time] < [Ticket Close Time] 
) 
     -- Your actual output 
select ATM, 
      [Ticket Open Time], 
     [Ticket Close Time], 
from  C 
order by ATM, 
     [Ticket Open Time] 
+1

+1 : 재귀 CTE는 그리 빠르지 않습니다. 아마도 Numbers 또는 Calendar 테이블/CTE에 대해 조인하는 것이 좋습니다. – RBarryYoung

+0

@Ann L. 위대한 노력.하지만 W ATM의 경우 티켓 열기 시간 = 2013-03-01 06 : 00 : 00.000 및 티켓 마감 시간 = 2013-03-01 06 : 45 : 00.000' .... 8 오전 6 시부 터 오전 6 시까 지 방치됩니다. – Shaggy