2012-08-03 6 views
1

에 두 행에서 시간 범위를 얻기 나는과 같이 로그인과 로그 아웃 시간을 추적 SQL 서버 2012의 테이블이 있습니다. (유형 1에 로그인하고, 제 2 형 로그 아웃이다)동일한 열

UserId Type InsertDate 
2134  1  20120803 06:32:02.230 
2134  1  20120803 10:12:24.350 
2134  2  20120803 10:29:21.550 
2134  2  20120803 14:10:34.220 
5915  1  20120802 14:57:57.453 
5915  2  20120802 16:59:00.477 

나는이 테이블을 조회 할 - 각 로그인/로그 아웃 쌍에 대한 초 단위로 계산 된 시간 범위와 사용자 ID의 그룹화 된 목록을 보여주고, 그래서 나는 같은 것을 끝낼 :

UserID Duration 
2134  1017 
5915  7263 

UPDATE : 개별 사용자에 대해 여러 세트의 로그인/로그 아웃 쌍이있을 수 있으며 해당 로그 아웃이없는 로그인이있을 수 있습니다. 해당 값이없는 로그인 또는 로그 아웃을 무시하고 싶습니다. 하나의 로그인과 거기 경우

+2

사용자가 항목을 두 쌍을 가지고 어떤 경우? 유형 1 또는 유형 2 항목이 누락 된 경우 어떻게해야합니까? –

+3

고려해야 할 엣지 케이스가 있습니까? 이러한 모든 행이 동일한 사용자에 대한 것이면 (가능한 경우) 동일한 결과 (동일한 사용자 ID) 또는 단일 행 (최대 기간을 다루는 단일 행 인 경우)이 있습니까? 하나의 '2'로 여러 개의 '1'이있을 수 있습니까? 간단한 예제를 기반으로 쿼리를 작성하는 것은 간단하지만 실제 데이터가 얼마나 가까운 지 궁금합니다. –

+0

사용자 중 한 명에게 추가로 로그인/로그 아웃을 추가하고, 로그 아웃 만있는 사용자와 원하는 출력을 업데이트하여 가장자리 상황 처리에 대한 기대치가 명확 해지도록 사용자를 추가하는 것이 좋습니다. –

답변

6

SQL Server 2012에서는 자체 조인과 집계가 약간 불필요합니다. 이 솔루션은 동일한 사용자가 여러 로그인을 처리합니다. 이전 버전의

DECLARE @t TABLE(UserID INT, [Type] TINYINT, InsertDate DATETIME); 

INSERT @t VALUES 
(2134,1,'20120803 10:12:24.350'), 
(2134,2,'20120803 10:29:21.550'), 
(2134,1,'20120803 11:22:24.350'), 
(2134,2,'20120803 11:47:21.550'), 
(5915,1,'20120802 14:57:57.453'), 
(5915,2,'20120802 16:59:00.477'); 

;WITH x AS (
    SELECT UserID, [Type], InsertDate, Prev = LAG(InsertDate, 1) OVER 
    (PARTITION BY UserID ORDER BY InsertDate) FROM @t 
) 
SELECT UserID, DATEDIFF(SECOND, Prev, InsertDate) FROM x WHERE [Type] = 2; 

-- or if you want cumulative time per user even if there are multiple login events: 

;WITH x AS (
    SELECT UserID, [Type], InsertDate, Prev = LAG(InsertDate, 1) OVER 
    (PARTITION BY UserID ORDER BY InsertDate) FROM @t 
) 
SELECT UserID, SUM(DATEDIFF(SECOND, Prev, InsertDate)) 
    FROM x WHERE [Type] = 2 GROUP BY UserID; 

당신은 더 정교한을 사용할 수

;WITH x AS 
(
    SELECT UserID, [Type], InsertDate, 
    rn = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY InsertDate) 
    FROM @t 
) 
SELECT x.UserID, DATEDIFF(SECOND, x.InsertDate, y.InsertDate) 
    FROM x INNER JOIN x AS y 
    ON x.UserID = y.UserID 
    AND x.rn = y.rn - 1 
    WHERE x.Type = 1 
    AND y.Type = 2; 
+3

SQL Server 2012에서 새로운 기능 (지연)을 배웠습니다. 좋은 대답! – praveen

+0

환상적 -이 트릭을했다. 지연 (및 납)에 대해서도 배웠습니다 - 매우 포괄적 인 대답 –

+0

@ChrisB 도움이 되니 기쁩니다. 물론 MIN/MAX 쿼리는 훨씬 간단하지만 각 사용자가 단일 로그인/로그 아웃 쌍만있는 경우에만 작동합니다. 질문의 샘플 데이터가 크게 단순화되어 여러 가지 유형의 가장자리 사례가 누락되었다고 가정합니다. –

0

select datediff(s, min(InsertDate), max(InsertDate)) as diff 
from your_table 
group by UserId 
+0

각 사용자는 테이블에 한 쌍의 항목 만 있다고 가정합니다. –

0

을 시도;

select UserId, DATEDIFF(second,Min(InsertDate),Max(InsertDate)) as Duration, 
from Table1 
Group By UserId 
+1

이 답변은 @ juergend (사용자 아이디 열을 출력에 추가 한 것을 제외하고는)와 동일합니다. –

+0

예 제가 저에게 편지를 쓰는 동안 답변이 게시되었다는 통지를받지 못했습니다. – saj

관련 문제