번호 시작시간 종료시간
1000 2016-11-10 09:00 2016-11-10 09:40
1000 2016-11-10 09:30 2016-11-10 09:50
1000 2016-11-10 10:00 2016-11-10 10:10
1000 2016-11-10 10:05 2016-11-10 10:10
1000 2016-11-10 10:05 2016-11-10 10:15
원하는 결과
>>
번호 총합
1000 65
검색해서 찾은 쿼리문으로 짜봤는데
결과값이 60이 나오네요 ㅠ 도와주세요
SELECT NO, SUM(DATEDIFF(MINUTE, Date1, Date2)) AS WorkTime
FROM
(
SELECT A.NO, A.Date1,
CASE WHEN A.Date2 < B.Date1 OR B.Date1 IS NULL THEN A.Date2 ELSE B.Date1 END AS Date2
FROM
(
SELECT NO, Date1, Date2, ROW_NUMBER() OVER (PARTITION BY NO ORDER BY Date1) AS NUM1
FROM DateTest
GROUP BY NO, Date1, Date2
) AS A
LEFT OUTER JOIN
(
SELECT NO, Date1, ROW_NUMBER() OVER (PARTITION BY NO ORDER BY Date1) AS NUM1
FROM DateTest
GROUP BY NO, Date1
) AS B
ON A.NUM1 = B.NUM1 - 1
) AS A
GROUP BY NO
Comment 6
-
건우아빠
2016.11.10 19:27
with dataas(select 1000 [번호], '2016-11-10 09:00' [시작시간] , '2016-11-10 09:40' [종료시간] union allselect 1000 ,'2016-11-10 09:30', '2016-11-10 09:50' union allselect 1000 ,'2016-11-10 10:00', '2016-11-10 10:10' union allselect 1000 ,'2016-11-10 10:05', '2016-11-10 10:10' union allselect 1000 ,'2016-11-10 10:05', '2016-11-10 10:15') , res as(select * , ROW_NUMBER() over( partition by [번호] order by [시작시간] , [종료시간] ) nofrom data) ,result as(select a.[번호] , case when a.[시작시간] < b.[종료시간] then b.[종료시간] else a.[시작시간] end [시작시간] , a.[종료시간]from res a left join res b on a.[번호] = b.[번호] and a.no = b.no + 1)select * , DATEDIFF (mi,[시작시간] , [종료시간] )from resultsum 내시면 될듯 합니다. -
하늘민
2016.11.11 09:13
답변 감사합니다.
위의 데이터에선 잘 작동하는데.
마지막 행의 시작시간이 10:05분이 아니고, 예를 들어 10:04분이다. 이러면 또 계산이 어긋나네요
사용자가 어떻게 입력할지가 안정해져있어서... ㅠ
-
항해자™
2016.11.11 18:33
아래처럼 하고, 합계만 count(*)로 구하면 되지 않을까,, 테스트 해 보았습니다,,,
그리고 67로 나오네요,,
각각 시작 시간인 09:00 과 10:00 을 제외해야 한다면, 65가 맞겠네요,,
create table #tmpTimes ( cTime datetime ) go truncate table #tmpTimes insert into #tmpTimes select dateadd(minute,cRows,'2016-11-01') from ( select top 100000 row_number() over(order by (select 1)) as cRows from syscolumns as a , syscolumns as b , syscolumns as c , syscolumns as d ) as a go ;with cteSample (cIdx, cStart, cLimit) as ( select 1000, '2016-11-10 09:00', '2016-11-10 09:40' union all select 1000, '2016-11-10 09:30', '2016-11-10 09:50' union all select 1000, '2016-11-10 10:00', '2016-11-10 10:10' union all select 1000, '2016-11-10 10:05', '2016-11-10 10:10' union all select 1000, '2016-11-10 10:05', '2016-11-10 10:15' ) select b.cTime from cteSample as a cross apply ( select cTime from #tmpTimes where cTime between a.cStart and a.cLimit ) as b group by cTime order by cTime go
-
하늘민
2016.11.12 13:52
이해가 잘안가기는 하는데 ㅠ
이런 방법도 있군요.
중간의 syscolumns에서 뽑아오는건 어떤 값이고 무슨 이유인가요
-
항해자™
2016.11.14 09:42
분 단위로 구성된 날짜 테이블입니다,,
실제로는 임시 테이블이 아닌, 미리 만들어 놓고 사용하는게 좋을 것 같구요,,,
날짜 컬럼에 인덱스가 있으면 더 좋을 수 있겠네요,,
누가 그랬던거 같은데 한 100년치 미리 만들어 놓으면 걱정 읎지 않을까요ㅎㅎ
더 좋은 방법은 다른분께서, 또 답변 달아 주시겠죠ㅎㅎ
-
jude
2017.01.05 08:55
sql server 2012는 LAG() , LEAD() 함수가 있어서 다행입니다.조금은 간단하게 쿼리를 만들수 있습니다.위에서 말씀하신것 처럼 10:04분으로 바꾸더라도 총 시간은 65분 이어야 합니다.아래 쿼리 참고해 보세요.with dataas(select 1000 [번호], '2016-11-10 09:00' [시작시간] , '2016-11-10 09:40' [종료시간] union allselect 1000 ,'2016-11-10 09:30', '2016-11-10 09:50' union allselect 1000 ,'2016-11-10 10:00', '2016-11-10 10:10' union allselect 1000 ,'2016-11-10 10:05', '2016-11-10 10:10' union allselect 1000 ,'2016-11-10 10:04', '2016-11-10 10:15' /* 05분을 04분으로 바꿔봤습니다.*/)SELECT NO,SUM(DATEDIFF(MINUTE,A.START_TIME,A.END_TIME)) SUM_MINUTEFROM (SELECT NO,START_TIME ORG_START_TIME,END_TIME ORG_END_TIME,BEF_END_TIME,CASE WHEN BEF_END_TIME IS NULL THEN START_TIMEELSE CASE WHEN START_TIME < BEF_END_TIME THEN BEF_END_TIMEELSE START_TIMEENDEND START_TIME,CASE WHEN BEF_END_TIME IS NULL THEN END_TIMEELSE CASE WHEN END_TIME < BEF_END_TIME THEN BEF_END_TIMEELSE END_TIMEENDEND END_TIMEFROM (SELECT [번호] NO,[시작시간] START_TIME,[종료시간] END_TIME,LAG([종료시간]) OVER(PARTITION BY [번호] ORDER BY [시작시간]) BEF_END_TIMEFROM data) A) AGROUP BY NO