需要查询帮助。我有一个表格,数据表示如下
userid TransactionTime FunctionKey
1018 2011-07-27 09:14:38.000 0
1018 2011-07-27 09:17:11.000 99
1018 2011-07-27 09:38:22.000 0
1018 2011-07-27 10:34:50.000 99
我需要一个会返回如下数据集的查询:
userid Intime Outtime
1018 2011-07-27 09:14:38.000 2011-07-27 09:17:11.000
1018 2011-07-27 09:38:22.000 2011-07-27 10:34:50.000
请帮助..
答案 0 :(得分:4)
declare @T table (userid int, TransactionTime datetime, FunctionKey int)
insert into @T values
(1018, '2011-07-27 09:14:38.000', 0),
(1018, '2011-07-27 09:17:11.000', 99),
(1018, '2011-07-27 09:38:22.000', 0),
(1018, '2011-07-27 10:34:50.000', 99),
(1019, '2011-07-27 09:14:38.000', 0),
(1019, '2011-07-27 09:17:11.000', 0),
(1019, '2011-07-27 09:38:22.000', 99),
(1020, '2011-07-27 09:14:38.000', 0),
(1020, '2011-07-27 09:17:11.000', 99),
(1020, '2011-07-27 09:38:22.000', 99)
;with cte as
(
select userid,
TransactionTime,
FunctionKey,
row_number() over(partition by userid order by TransactionTime) as rn
from @T
)
select C1.userid,
C1.TransactionTime as InTime,
C2.TransactionTime as OutTime
from cte as C1
left outer join cte as C2
on C1.userid = C2.userid and
C1.rn + 1 = C2.rn
where C1.FunctionKey = 0
结果:
userid InTime OutTime
----------- ----------------------- -----------------------
1018 2011-07-27 09:14:38.000 2011-07-27 09:17:11.000
1018 2011-07-27 09:38:22.000 2011-07-27 10:34:50.000
1019 2011-07-27 09:14:38.000 2011-07-27 09:17:11.000
1019 2011-07-27 09:17:11.000 2011-07-27 09:38:22.000
1020 2011-07-27 09:14:38.000 2011-07-27 09:17:11.000
答案 1 :(得分:2)
WITH
ordered AS
(
SELECT
ROW_NUNBER() OVER (PARTITION BY userid ORDER BY TransactionTime, FunctionKey) item_id,
*
FROM
myTable
)
, logins AS
(
SELECT * FROM ordered WHERE FunctionKey = 0
)
, logouts AS
(
SELECT * FROM ordered WHERE FunctionKey = 99
)
SELECT
COALESCE([logins].userid, [logouts].userid),
[logins].TransactionTime,
[logouts].TransactionTime
FROM
[logins]
FULL OUTER JOIN
[logouts]
ON [logouts].userid = [logins].userid
AND [logouts].item_id = [logins].item_id + 1
AND [logouts].FunctionKey <> [logins].FunctionKey
ORDER BY
COALESCE([logins].TransactionTime, [logouts].TransactionTime)
或者,这个通过第一次登录来处理登录序列,并通过上次登出来处理logogut序列。
WITH
ordered AS
(
SELECT
ROW_NUNBER() OVER (PARTITION BY userid ORDER BY TransactionTime, FunctionKey)
-
ROW_NUMBER() OVER (PARTITION BY userid, FunctionKey ORDER BY TransactionTime)
AS group_id,
*
FROM
myTable
)
,
filtered AS
(
SELECT
userid,
FunctionKey,
CASE WHEN FunctionKey = 0 THEN MIN(TransactionTime) ELSE MAX(TransactionTime) END AS TransactionTime
FROM
ordered
GROUP BY
userid,
FunctionKey,
group_id
)
,
sequenced AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY userid ORDER BY TransactionTime, FunctionKey) AS item_id,
*
FROM
filtered
)
, logins AS
(
SELECT * FROM sequenced WHERE FunctionKey = 0
)
, logouts AS
(
SELECT * FROM sequenced WHERE FunctionKey = 99
)
SELECT
COALESCE([logins].userid, [logouts].userid),
[logins].TransactionTime,
[logouts].TransactionTime
FROM
[logins]
FULL OUTER JOIN
[logouts]
ON [logouts].userid = [logins].userid
AND [logouts].item_id = [logins].item_id + 1
AND [logouts].FunctionKey <> [logins].FunctionKey
ORDER BY
COALESCE([logins].TransactionTime, [logouts].TransactionTime)
答案 2 :(得分:0)
将表格加入自身,每个时间戳都有一个时间戳:
select
t1.userid,
t1.TransactionTime as InTime
t2.TransactionTime as Outtime
from mytable t1
join mytable t2 on t2.userid = t1.userid and t2.FunctionKey = 99
where t1.FunctionKey = 0;