需要查询帮助

时间:2011-07-28 10:16:16

标签: sql sql-server-2008 select

需要查询帮助。我有一个表格,数据表示如下

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 

请帮助..

3 个答案:

答案 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;