从同一列中的两行获取时间和超时

时间:2015-04-07 11:40:10

标签: sql sql-server select join rows

 VriHistoryID OccurredAt              VriHistoryEventID InitiatorID
    ------------ ----------------------- ----------------- -----------
633          2013-01-01 07:41:10.567 8                 6
636          2013-01-14 11:52:34.373 7                 4
637          2013-01-14 11:52:41.780 8                 4
638          2013-01-14 12:17:12.300 7                 4
639          2013-01-14 12:17:23.207 8                 4
640          2013-01-14 12:39:55.803 7                 4
641          2013-01-14 12:55:58.003 7                 4
642          2013-01-14 12:56:47.360 8                 4
643          2013-01-14 13:43:20.453 8                 4
644          2013-01-14 16:46:19.143 7                 38
645          2013-01-14 16:47:05.397 8                 38
646          2013-01-14 17:16:30.253 7                 38
647          2013-01-14 17:17:27.193 8                 38
648          2013-01-14 17:17:47.897 7                 38
649          2013-01-14 17:23:04.640 8                 38
650          2013-01-14 17:24:40.250 7                 38
651          2013-01-14 17:25:23.360 8                 38
654          2013-01-14 21:57:56.403 7                 5
656          2013-01-14 21:59:04.280 8                 5
659          2013-01-15 04:13:38.783 7                 38
660          2013-01-15 04:14:03.283 8                 38
661          2013-01-15 02:59:26.977 7                 3
662          2013-01-15 03:00:35.840 8                 3
663          2013-01-15 03:08:01.693 7                 39
664          2013-01-15 03:08:26.023 8                 39
665          2013-01-15 03:12:49.013 7                 39
666          2013-01-15 03:13:46.000 8                 39
668          2013-01-14 23:36:23.880 8                 40
669          2013-01-14 23:40:01.337 7                 40
672          2013-01-14 23:40:39.150 8                 40
677          2013-01-15 04:35:12.970 7                 3
678          2013-01-15 02:36:52.707 7                 5
697          2013-01-15 02:53:16.810 8                 5
698          2013-01-15 02:54:07.107 7                 5
700          2013-01-15 04:58:22.440 8                 3
703          2013-01-15 05:22:49.480 7                 3
705          2013-01-15 05:44:43.357 8                 3
706          2013-01-15 05:47:26.487 7                 3
707          2013-01-15 05:47:42.597 8                 3
708          2013-01-15 03:54:52.840 8                 5
709          2013-01-15 03:55:38.920 7                 5
711          2013-01-15 05:55:44.000 8                 5
712          2013-01-15 03:56:37.687 7                 5
714          2013-01-15 03:56:43.920 8                 5
715          2013-01-15 04:10:54.820 7                 5
717          2013-01-15 04:11:08.443 8                 5
718          2013-01-15 04:12:32.947 7                 5
720          2013-01-15 04:12:38.743 8                 5
721          2013-01-15 04:15:47.843 7                 5
723          2013-01-15 04:15:54.640 8                 5
724          2013-01-15 06:20:12.350 7                 3
725          2013-01-15 06:20:38.193 8                 3
726          2013-01-15 04:20:46.910 7                 5
728          2013-01-15 04:20:49.897 8                 5
729          2013-01-15 06:15:14.463 7                 5
731          2013-01-15 10:32:13.537 7                 38
732          2013-01-15 11:10:14.990 7                 38
733          2013-01-15 11:10:25.913 8                 38
738          2013-01-15 11:24:29.533 8                 38
739          2013-01-15 11:26:28.020 7                 38
741          2013-01-15 11:36:24.213 8                 38
742          2013-01-15 11:43:19.457 7                 38
743          2013-01-15 11:44:49.100 8                 38
761          2013-01-15 13:09:51.080 7                 4
762          2013-01-15 13:10:04.207 8                 4
763          2013-01-15 13:10:21.690 7                 3
764          2013-01-15 13:12:08.617 8                 3
765          2013-01-15 13:13:25.163 7                 3
766          2013-01-15 13:14:49.400 8                 3
767          2013-01-15 13:17:20.230 7                 3
768          2013-01-15 13:17:43.467 8                 3
771          2013-01-15 14:58:25.400 7                 3
774          2013-01-15 13:18:37.350 8                 5
779          2013-01-15 20:28:59.957 7                 5

我有一个使用VriHistoryEventID = 7保持登录的列occuredAt和使用VriHistoryEventID = 8的LogOut现在,我想创建一个查询,可以按InitiatorID选择数据组,然后按日期登录并在同一行中注销

谢谢

2 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情

SELECT InitiatorID,
MAX(CASE WHEN VriHistoryEventID = 7 THEN OccurredAt ELSE NULL END) [Login],
MAX(CASE WHEN VriHistoryEventID = 8 THEN OccurredAt ELSE NULL END) [Logout]
FROM @table
GROUP BY InitiatorID,CONVERT(DATE,OccurredAt)

编辑2 此查询将在一天内显示多个登录和注销

DECLARE @table TABLE
(
    VriHistoryID INT,
    OccurredAt DATETIME,
    VriHistoryEventID INT,
    InitiatorID INT
)
INSERT INTO @table values(1,'2012-08-23 03:28:32.000',8,NULL)
INSERT INTO @table values(4,'2012-08-24 03:47:19.640',8,5)
INSERT INTO @table values(5,'2012-08-24 03:47:50.170',7,5)
INSERT INTO @table values(7,'2012-08-24 03:48:05.407',8,5)

;WITH CTE AS 
(
SELECT
    InitiatorID,
    VriHistoryEventID,
    (CASE WHEN VriHistoryEventID = 7 THEN OccurredAt ELSE NULL END) [Login],
    (CASE WHEN VriHistoryEventID = 8 THEN OccurredAt ELSE NULL END) [Logout],
    ROW_NUMBER() OVER(PARTITION BY InitiatorID,VriHistoryEventID ORDER BY OccurredAt) rn
FROM @table
)
SELECT InitiatorID,MIN(Login) Login,MIN(Logout) Logout
FROM CTE C1
GROUP BY InitiatorID,rn
ORDER BY InitiatorID,rn

编辑3 根据预期的更新输出更新了示例SQL。 见SQL Fiddle

CREATE TABLE #table
(
    VriHistoryID INT,
    OccurredAt DATETIME,
    VriHistoryEventID INT,
    InitiatorID INT
)
INSERT INTO #table values(1,'2012-08-23 03:28:32.000',8,NULL)
INSERT INTO #table values(4,'2012-08-24 03:47:19.640',8,5)
INSERT INTO #table values(5,'2012-08-24 03:47:50.170',7,5)
INSERT INTO #table values(7,'2012-08-24 03:48:05.407',8,5)

;WITH CTE AS 
(
SELECT
    InitiatorID,
    VriHistoryEventID,
    CONVERT(DATE,OccurredAt) OccurredDate,
    (CASE WHEN VriHistoryEventID = 7 THEN OccurredAt ELSE NULL END) [Login],
    (CASE WHEN VriHistoryEventID = 8 THEN OccurredAt ELSE NULL END) [Logout],
    ROW_NUMBER() OVER(PARTITION BY InitiatorID,CONVERT(DATE,OccurredAt), VriHistoryEventID ORDER BY OccurredAt) rn
FROM #table
)
SELECT InitiatorID,OccurredDate ,LEFT(CONVERT(VARCHAR(10),MIN([Login]),114),5) Login,LEFT(CONVERT(VARCHAR(10),MIN([Logout]),114),5) Logout
FROM CTE C1
GROUP BY InitiatorID,OccurredDate,rn
ORDER BY InitiatorID,OccurredDate,rn

答案 1 :(得分:0)

对于SQL Server 2012 +:

DECLARE @t TABLE
    (
      ID INT ,
      D DATETIME ,
      E INT ,
      I INT
    )

INSERT  INTO @t
VALUES  ( 1, '2012-08-23 03:28:32.000', 8, NULL ),
        ( 4, '2012-08-24 03:47:19.640', 8, 5 ),
        ( 5, '2012-08-24 03:47:50.170', 7, 5 ),
        ( 7, '2012-08-24 03:48:05.407', 8, 5 ),
        ( 8, '2012-08-29 04:09:07.120', 7, 11 ),
        ( 9, '2012-08-29 04:09:38.433', 8, 11 ),
        ( 10, '2012-08-29 04:35:32.580', 7, 11 ),
        ( 11, '2012-08-29 05:14:26.110', 7, 5 ),
        ( 13, '2012-08-29 05:14:58.877', 8, 5 ),
        ( 14, '2012-08-29 22:29:04.290', 7, 9 );


WITH    cte1
          AS ( SELECT   * ,
                        CAST(D AS DATE) AS dt ,
                        ( CASE WHEN FIRST_VALUE(E) OVER ( PARTITION BY I,
                                                          CAST(D AS DATE) ORDER BY D ) = 7
                               THEN 0
                               ELSE 1
                          END
                          + ROW_NUMBER() OVER ( PARTITION BY I,
                                                CAST(D AS DATE) ORDER BY D ) )
                        % 2 AS rn
               FROM     @t
             ),
        cte2
          AS ( SELECT   * ,
                        SUM(rn) OVER ( PARTITION BY I, dt ORDER BY D ) AS s
               FROM     cte1
             ),
        cte3
          AS ( SELECT   dt ,
                        I ,
                        s ,
                        MIN(D) AS MIND ,
                        MAX(D) AS MAXD ,
                        MIN(E) AS MINE ,
                        MAX(E) AS MAXE
               FROM     cte2
               GROUP BY dt ,
                        I ,
                        s
             )
    SELECT  I AS InitiatorID ,
            dt AS Date ,
            CASE MINE
              WHEN 7
              THEN CAST(DATEPART(hh, MIND) AS NVARCHAR(2)) + ':'
                   + CAST(DATEPART(mi, MIND) AS NVARCHAR(2))
              ELSE NULL
            END AS InTime ,
            CASE MAXE
              WHEN 8
              THEN CAST(DATEPART(hh, MAXD) AS NVARCHAR(2)) + ':'
                   + CAST(DATEPART(mi, MAXD) AS NVARCHAR(2))
              ELSE NULL
            END AS OutTime
    FROM    cte3
    ORDER BY I ,
            dt ,
            s

输出:

InitiatorID Date        InTime  OutTime
NULL        2012-08-23  NULL    3:28
5           2012-08-24  NULL    3:47
5           2012-08-24  3:47    3:48
5           2012-08-29  5:14    5:14
9           2012-08-29  22:29   NULL
11          2012-08-29  4:9     4:9
11          2012-08-29  4:35    NULL