我需要进行查询以显示每天的入口(Where TerminalID = 1)和退出(Where TerminalID = 2),但如果UserID只有这一天的退出标记,请使用08:00:00 on入口价值,如果没有退出标记,请在当天20:00:00设置退出值,我需要知道IDUser在这里的天数以及每天有多少时间,这是我的餐桌:
ID TransactionTime TerminalID UserID
1 2014-04-01 08:59 1 1
2 2014-04-01 09:09 1 1
3 2014-04-01 09:59 2 1
4 2014-04-01 10:59 1 1
5 2014-04-01 18:59 2 1
6 2014-05-01 08:59 1 1
7 2014-04-01 09:59 1 2
8 2014-04-01 18:59 2 2
9 2014-05-01 08:59 2 2
我需要的结果是:
UserID MarkEntrance MarkExit TimeHere
1 2014-04-01 08:59 2014-04-01 09:59 01:00:00
1 2014-04-01 10:59 2014-04-01 18:59 08:00:00
1 2014-05-01 08:59 2014-05-01 20:00 11:01:00
我可以这样做:
SELECT TOP 1000
pna.UserID
,Convert(char(10),pna.TransactionTime, 103) as DateOfMark
,MarkEntrance =
CASE WHEN
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
,MarkExit =
CASE WHEN
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END
,TimeHere =
Convert(char(8),
CASE WHEN
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END -
CASE WHEN
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
, 14)
FROM NGAC_AUTHLOG as pna
GROUP BY pna.UserID, Convert(char(10),pna.TransactionTime, 103)
但在我的查询中,我只知道UserID的第一个入口和最后一个出口,但他每天可以有很多标记。
(我使用MIN和MAX,但这样只显示一个大标记,合并当天的所有标记)
答案 0 :(得分:1)
尝试这样的事情。第一个联合部分匹配出口和孤儿入口的所有记录。工会的第二部分处理孤立的退出记录。
解决方案1:
SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
FROM NGAC_AUTHLOG B
WHERE B.TerminalID = 2
AND B.UserID = A.UserID
AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1
UNION ALL
--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), max(A.TransactionTime), 101)), max(A.TransactionTime)
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2
AND EXISTS
(SELECT 1
FROM
(SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T2Date, COUNT(*) T2Count
FROM NGAC_AUTHLOG
WHERE TerminalID = 2
GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) X
LEFT JOIN
(SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T1Date, COUNT(*) T1Count
FROM NGAC_AUTHLOG
WHERE TerminalID = 1
GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) Y
ON X.UserID = Y.UserID
AND X.T2Date = Y.T1Date
WHERE X.T2Count > ISNULL(Y.T1Count,0)
AND X.UserID = A.UserID
AND X.T2Date = CONVERT(VARCHAR(10), TransactionTime, 101)
)
GROUP BY A.UserID, CONVERT(VARCHAR(10), TransactionTime, 101)
) X
解决方案2: 假设有一个孤儿退出记录,那个用户当天只有1个退出记录
SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
FROM NGAC_AUTHLOG B
WHERE B.TerminalID = 2
AND B.UserID = A.UserID
AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1
UNION ALL
--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), A.TransactionTime, 101)), A.TransactionTime
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2
AND NOT EXISTS
(SELECT 1
FROM NGAC_AUTHLOG B
WHERE B.TerminalID = 1
AND A.UserID = B.UserID
AND CONVERT(VARCHAR(10), A.TransactionTime, 101) = CONVERT(VARCHAR(10), B.TransactionTime, 101))
) X
答案 1 :(得分:0)
尝试这样的事情。注意我还没有运行查询,所以可能会出现一个简单的语法错误(主要是转换 - 真的不确定),如果有问题,请在评论中告诉我。
;WITH minEntranceInDay as(
SELECT MIN(transactionTime) EntranceTime,Convert(DateTime( Convert(char(10),na.TransactionTime)), 103) Day, UserId
FROM NGAC_AUTHLOG WHERE TerminalId = 1
GROUP BY Convert(DateTime( Convert(char(10),na.TransactionTime)), 103), UserId
), maxExitInDay as(
SELECT MAX(transactionTime) ExitTime, Convert(DateTime( Convert(char(10),na.TransactionTime)) Day, UserId
FROM NGAC_AUTHLOG WHERE TerminalId = 2
GROUP BY Convert(DateTime( Convert(char(10),na.TransactionTime)), 103), UserId
), usersAndDates as(
SELECT DISTINCT Convert(DateTime( Convert(char(10),na.TransactionTime)) Day, UserId
FROM NGAC_AUTHLOG
), GroupedData As (
SELECT ud.UserId, COALESCE(me.minEntranceInDay,Dateadd(h,8,ud.Day)) EntranceTime, COALESCE(mx.maxExitInDay,Dateadd(h,20,ud.Day)) ExitDate
FROM usersAndDates ud
LEFT JOIN minEntranceInDay me ON me.UserId = ud.UserId AND me.Day = ud.Day
LEFT JOIN maxExitInDay mx ON mx.UserId = ud.UserId AND mx.Day = ud.Day
)
SELECT *, DATEDIFF(h,EntranceTime,ExitTime)+":"+DATEDIFF(m,EntranceTime,ExitTime)+":"+DATEDIFF(s,EntranceTime,ExitTime) TimeHere
FROM GroupedData