date | status | bigo | ... |
2016-06-01 09:00 | 시작 |
|
|
2016-06-01 09:30 | 일시정지 |
|
|
2016-06-01 09:40 | 재시작 |
|
|
2016-06-01 10:00 | 종료 |
|
|
|
|
|
|
|
|
|
|
상기와 같은 Table이 있을경우
순수한 작업 시간을 구하려면 어덯게 쿼리를 하는것이 좋을까요?
(위 Table 기준 순수 작업시간은 50분 입니다)
아니면 다른 Table를 생성해야 할까요?
Comment 4
-
무념
2016.06.01 15:31
-
주크
2016.06.01 15:56
답변 감사합니다. 참고하도록 하겠습니다. ^^
-
minsouk
2016.06.02 00:55
use tempdb
goif object_id('tblx') is not null
drop table tblx
gocreate table tblx
(cDate datetime
,cStatus varchar(20)
,cGroupId int
)
goinsert into tblx values
('2016-06-01 09:00:00.000', '시작 ', 1)
,('2016-06-01 09:30:00.000', '일시정지', 1)
,('2016-06-01 09:40:00.000', '재시작', 1)
,('2016-06-01 09:41:00.000', '일시정지', 1)
,('2016-06-01 09:50:00.000', '재시작', 1)
,('2016-06-01 10:00:00.000', '종료', 1)
,('2016-06-01 09:00:00.000', '시작 ', 2)
,('2016-06-01 09:20:00.000', '일시정지', 2)
,('2016-06-01 09:40:00.000', '재시작', 2)
,('2016-06-01 10:00:00.000', '종료', 2)select a.cGroupId, sum(datediff(minute, a.cDate, b.cDate)) cWorkingMinute
from
(
select *
from tblx
where cStatus in ('시작', '재시작')
) a
outer apply
(
select top 1 *
from tblx
where cGroupId = a.cGroupId
and cDate > a.cDate
and cStatus in ('종료', '일시정지')
order by cDate
) b
group by a.cGroupId -
zom6ic
2016.06.02 18:08
WITH MST AS
(
SELECT '2016-05-07 07:00' AS DT, '시작' AS STAT UNION ALL
SELECT '2016-05-07 08:00', '일시정지' UNION ALL
SELECT '2016-05-07 10:00', '종료' UNION ALL
SELECT '2016-06-01 09:00', '시작' UNION ALL
SELECT '2016-06-01 09:30', '일시정지' UNION ALL
SELECT '2016-06-01 10:00', '재시작' UNION ALL
SELECT '2016-06-01 10:10', '일시정지' UNION ALL
SELECT '2016-06-01 10:20', '재시작' UNION ALL
SELECT '2016-06-01 10:30', '일시정지' UNION ALL
SELECT '2016-06-02 11:00', '종료'
)
SELECT *
INTO #TMP
FROM MSTSELECT A.시작_DATE AS 시작
,A.종료_DATE AS 종료
,MAX(A.ALLTIME) AS 총시간
,SUM(A.IDLETIME) AS 정지시간
,MAX(A.ALLTIME) - SUM(A.IDLETIME) AS 가동시간
FROM
(
SELECT *
FROM
(
SELECT A.DT AS 시작_DATE
,B.DT AS 종료_DATE
,DATEDIFF(MINUTE, A.DT, B.DT) AS ALLTIME
FROM
(
SELECT *
FROM #TMP
WHERE STAT IN ('시작')
) A
OUTER APPLY
(
SELECT TOP 1 B.DT
FROM #TMP B
WHERE A.DT < B.DT
AND B.STAT IN ('종료')
ORDER BY B.DT ASC
) B
) A
LEFT JOIN
(
SELECT A.DT AS S_DATE
,B.DT AS E_DATE
,DATEDIFF(MINUTE, A.DT, B.DT) AS IDLETIME
FROM
(
SELECT DT
FROM #TMP
WHERE STAT IN ('일시정지')
) A
OUTER APPLY
(
SELECT TOP 1 B.DT
,B.STAT
FROM #TMP B
WHERE A.DT < B.DT
AND B.STAT IN ('재시작', '종료')
ORDER BY B.DT ASC
) B
) B ON (B.S_DATE BETWEEN A.시작_DATE AND A.종료_DATE)
AND (B.E_DATE BETWEEN A.시작_DATE AND A.종료_DATE)
) A
GROUP BY A.시작_DATE, A.종료_DATEDROP TABLE #TMP
1. 각 작업별 ID와 해당 아이디의 작업 시퀀스 테이블을 만들고
2. 정지 이벤트 처리 저장 프로시저에서 작업ID와 해당 작업의 시퀀스 전 ID를 참조하여
3. 작업시간을 계산해서
4. 정지 시퀀스에 시간을 기록하면
5. 작업 ID별 시간을 구할 수 있을 것 같은데요.
현재의 인덱싱도 되지 않은 로그성 테이블로 계산하는건 아닌것 같아요.