nEventLogIdn | nDateTime | nReaderIdn | nEventIdn | nUserID | nIsLog | nTNAEvent | nIsUseTA | nType |
2001613 |
1401784173 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
2000546 |
1401663527 |
32166 |
55 |
183 |
0 |
1 |
0 |
0 |
2000346 |
1401611581 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
2000113 |
1401526007 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
1999986 |
1401490693 |
32165 |
55 |
183 |
1 |
1 |
0 |
0 |
1999635 |
1401439378 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
1999497 |
1401397114 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
1999301 |
1401352654 |
32166 |
55 |
183 |
0 |
0 |
0 |
0 |
위와같이 데이터가 있을 경우 nDateTime 가 출퇴근시간이고 출근일 경우 nTNAEvent 가 0 퇴근일 경우 1 이 됩니다.
단지 출근이나 퇴근기록이 여러개가 있을수 있어 출근은 nDateTime 가 같은날 최소값일때 퇴근은 최대값일때로 뽑아야 합니다.
문제는 주간 야간 2교대로 되어있어서 만약 nTNAEvent가 0인데 시간이 17시 보다 크면 야간조로 판단해서
다음날 09시 이전에 최대 nDateTime으로 해서 퇴근을 조회하고 싶습니다. 정리하자면 아래 표와 같습니다.
Nuserid | ADATE |
nTNAEvent1 |
STIME |
nTNAEvent2 |
ETIME |
183 |
2014-05-31 |
0 |
08:46:47 |
1 |
08:46:47 |
183 |
2014-05-30 |
0 |
08:42:58 |
1 |
22:58:13 |
183 |
2014-05-29 |
0 |
08:37:34 |
1 |
20:58:34 |
183 |
2014-05-28 |
0 |
08:54:25 |
1 |
20:59:26 |
183 |
2014-05-27 |
0 |
08:32:40 |
1 |
22:58:05 |
183 |
2014-05-26 |
0 |
08:51:05 |
1 |
21:00:09 |
183 |
2014-05-24 |
0 |
08:47:22 |
1 |
20:58:39 |
부족한 쿼리는 아래 처럼 했지만 주야간구분과 nTNAEvent1,nTNAEvent2를 어떻게 처리해야 될지 헤매고 있습니다.
SELECT Nuserid
, CONVERT(CHAR(10), DATEADD(s,ndatetime,'1970-01-01 00:00:00'), 121) ADATE
, MIN(SUBSTRING(CONVERT(VARCHAR(30),DATEADD(s,ndatetime,'1970-01-01 00:00:00'),121),12,8) ) STIME
, MAX(SUBSTRING(CONVERT(VARCHAR(30),DATEADD(s,ndatetime,'1970-01-01 00:00:00'),121),12,8) ) ETIME
FROM TB_EVENT_LOG
WHERE nUserID=183 AND CONVERT(CHAR(10), DATEADD(s,ndatetime,'1970-01-01 00:00:00'), 121) BETWEEN '2014-01-01' AND '2014-05-31'
GROUP BY Nuserid,CONVERT(CHAR(10), DATEADD(s,ndatetime,'1970-01-01 00:00:00'), 121)
ORDER BY 2 DESC
Comment 2
-
다은빈아빠
2014.06.03 16:11
-
같은날 주간조 출근과 17시 이후 출근데이터가 같이 있어도 출근은 항상 MIN으로 뽑아야 하나요??
DECLARE @DATA TABLE (nEventLogIdn INT, nDateTime INT, nReaderIdn INT, nEventIdn INT, nUserID INT, nIsLog INT, nTNAEvent INT, nIsUseTA INT, nType INT)
INSERT @DATA SELECT 2001613,1401784173,32166,55,183,0,0,0,0
INSERT @DATA SELECT 2000546,1401663527,32166,55,183,0,1,0,0
INSERT @DATA SELECT 2000346,1401611581,32166,55,183,0,0,0,0
INSERT @DATA SELECT 2000113,1401526007,32166,55,183,0,0,0,0
INSERT @DATA SELECT 1999986,1401490693,32165,55,183,1,1,0,0
INSERT @DATA SELECT 1999635,1401439378,32166,55,183,0,0,0,0
INSERT @DATA SELECT 1999497,1401397114,32166,55,183,0,0,0,0
INSERT @DATA SELECT 1999301,1401352654,32166,55,183,0,0,0,0
SELECT nUserID, nTNAEvent, nDateTime = CONVERT(CHAR(30), DATEADD(S, nDateTime,'1970-01-01'), 121) FROM @DATA ORDER BY 3, 2
SELECT *
FROM (SELECT nUserID,
nDate = CONVERT(CHAR(10), DATEADD(S, nDateTime,'1970-01-01'), 121),
nTime = MIN(SUBSTRING(CONVERT(VARCHAR(30),DATEADD(S, nDateTime,'1970-01-01'), 121), 12, 8))
FROM @DATA
WHERE nTNAEvent = 0
GROUP BY nUserID, CONVERT(CHAR(10), DATEADD(S, nDateTime,'1970-01-01'), 121)) A FULL OUTER JOIN
(SELECT nUserID,
nDate = CONVERT(CHAR(10), DATEADD(S, nDateTime,'1970-01-01'), 121),
nTime = MAX(SUBSTRING(CONVERT(VARCHAR(30),DATEADD(S, nDateTime,'1970-01-01'), 121), 12, 8))
FROM @DATA
WHERE nTNAEvent = 1
GROUP BY nUserID, CONVERT(CHAR(10), DATEADD(S, nDateTime,'1970-01-01'), 121)) B ON A.nUserID = B.nUserID AND A.nDate = CASE WHEN A.nTime >= '17' THEN DATEADD(D, 1, B.nDate) ELSE B.nDate END
ORDER BY 1 DESC
원하시는 대로 뽑아봤는데 데이터는 원하시는대로 안나온거 같습니다. -_-;;
제 쿼리의 핵심은 출근데이터와 퇴근데이터를 따로 인라인 뷰로 만든다음 조인할때 17시보다 크만 하루 더해서 조인하는 것입니다.
그런데 같은 날의 출근데이터가 여럿일 경우 MIN을 취하라고 해서
5월 29일의 경우 출근데이터가 08시랑 20시가 두번 있는데 08시만 취하게 됐습니다.
그래서 실제로 주어진 데이터로는 야간조 데이터는 안나오네요.
게다가 조인할때조차 함수를 써야해서 속도는 극악일겁니다.
일단 테이블에 날짜를 따로 분리해서 인덱스를 걸어야 할거 같고 날짜 데이터도 DATETIME으로 바꾸시는게 좋을거 같습니다.
질문을 잘못했는지 답변주시는분들이 없네요 ㅠㅠ