2011-07-28 6 views
0

が必要です。私は、このようなデータセットを返しますクエリを必要とするデータはこのは、クエリの助けが必要クエリのヘルプ

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

Funtionkeyが0の場合、そのIntime、それが99のときOuttime –

+0

'スプリアス'データに対処する必要はありますか? (同時にログインとログアウト、ログイン続いログイン、ログアウト続いログアウトなど、など) – MatBailie

+0

なぜこの質問にdownvotes!?!?私の質問でダウン投票があり、なぜそれが私donnoこのway..Andに(ログインログイン続く、ログアウト、などなどが続くログアウト)する必要があります – MatBailie

答えて

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 
+0

にも、レコード3は、すべてのログアウトを前提としていが、すぐにログインが付け加えられ、ログインがimmeditatelyログインが付け加えされることはありません。 OPは明示的ではないので+1。 – MatBailie

+0

それは素晴らしいMikaelを働かせます...しかし、2つの連続する行が同じFunctionKey値を持つ場合はどうなりますか? –

+0

@Tanvir - どのようにそのシナリオに対処したいですか? (これで私の答えディール一つの方法は、別のオプションは*最後*「複製」、ログアウトし、すべてが、しかし、すべてをフィルタリングすることです*最初*「複製」ログインが。あなたが望むものを知らず、私たちはあなたを与えることができません鋳鉄の回答) – MatBailie

0

は、それ自体にテーブルに参加してくださいヘルプを、それぞれから1つのタイムスタンプを取る:

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; 
+1

この意志試合レコード2及び4にレコード1、レコード2と4 – MatBailie

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) 
関連する問題