2016-02-22 21 views
6

私はユーザーの履歴のテーブルを持っており、ユーザーが特定のユーザー名を保持している日付範囲を探しています。この表は、トリガーによって満たされる監査表です。したがって、ユーザー名だけでなく、ユーザーに変更があるたびに項目が入ります。私は、各行の日付範囲を取得するには、この操作を行うことができます。テーブルを分割して日付範囲を取得する

出力
CREATE TABLE #LoginHistory 
(
    LoginHistoryID INT IDENTITY(1,1), 
    LoginID INT, 
    Username VARCHAR(32), 
    StartDate DATETIME 
) 

INSERT INTO #LoginHistory (LoginID, Username, StartDate) VALUES 
(1, 't', '2016-01-01'), 
(1, 't', '2016-01-02'), 
(1, 't', '2016-01-04'), 
(1, 'test', '2016-01-05'), 
(2, 't', '2016-01-08'), 
(2, 'tom', '2016-01-09'), 
(1, 'test', '2016-01-15'), 
(1, 't', '2016-02-01') 

SELECT 
    LoginID, 
    Username, 
    StartDate, 
    EndDate = LEAD(StartDate) OVER (PARTITION BY LoginID ORDER BY StartDate ASC) 
FROM #LoginHistory 
WHERE LoginID = 1 
ORDER BY StartDate ASC 

DROP TABLE #LoginHistory 

LoginID Username StartDate    EndDate 
1  t   2016-01-01 00:00:00.000 2016-01-02 00:00:00.000 
1  t   2016-01-02 00:00:00.000 2016-01-04 00:00:00.000 
1  t   2016-01-04 00:00:00.000 2016-01-05 00:00:00.000 
1  test  2016-01-05 00:00:00.000 2016-01-15 00:00:00.000 
1  test  2016-01-15 00:00:00.000 2016-02-01 00:00:00.000 
1  t   2016-02-01 00:00:00.000 NULL 

しかし、私が本当にしたいことは一つの行がありますように、各ユーザ名の長さを崩壊することですユーザーがユーザー名を保持した日付範囲ごとに基本的に、私はこの出力を探しています:

LoginID Username StartDate    EndDate 
1  t   2016-01-01 00:00:00.000 2016-01-05 00:00:00.000 
1  test  2016-01-05 00:00:00.000 2016-02-01 00:00:00.000 
1  t   2016-02-01 00:00:00.000 NULL 

これらの行を正しく折りたたむにはどうすればいいですか?

+0

良い質問のためのUpvote:copy'n'pasteのためのサンプルシナリオ、独自のアプローチ、間違った出力期待される出力。 – Shnugo

答えて

3

次のクエリを使用することができます。

SELECT LoginID, 
     Username, 
     MIN(StartDate) AS StartDate, 
     MAX(EndDate) AS EndDate 
FROM (
    SELECT 
     LoginID, 
     Username, 
     StartDate, 
     EndDate = LEAD(StartDate) OVER (PARTITION BY LoginID 
             ORDER BY StartDate ASC), 
     ROW_NUMBER() OVER (ORDER BY StartDate) - 
     ROW_NUMBER() OVER (PARTITION BY LoginID, Username 
         ORDER BY StartDate) AS grp 
    FROM #LoginHistory 
    WHERE LoginID = 1) AS t 
GROUP BY LoginID, Username, grp 
ORDER BY StartDate ASC 

grpは、あなたが同じLoginID, Username値を持つ連続し行を識別するのに役立ちます。

+0

美しい;ありがとう! – zimdanen

関連する問題