SQL-根据特定条件从下一行获取值

时间:2019-05-15 23:16:20

标签: sql sql-server

我有下表:

| ID | Ref | Type |              LogTime |
|----|-----|------|----------------------|
|  1 |  AA |    1 | 2019-05-03 18:30:01  |
|  2 |  BB |    1 | 2019-05-03 19:42:02  |
|  3 |  AA |    3 | 2019-05-04 12:30:03  |
|  4 |  BB |    3 | 2019-05-05 19:42:04  |
|  5 |  AA |    1 | 2019-05-06 20:55:05  |

我想列出Type = 1的所有行,并包括Ref值相等且Type = 3的LogTime的值

类似这样的东西:

| ID | Ref | Type |              LogTime |        LogTime_Type3 |
|----|-----|------|----------------------|----------------------|
|  1 |  AA |    1 | 2019-05-03 18:30:01  | 2019-05-04 12:30:03  |
|  2 |  BB |    1 | 2019-05-03 19:42:02  | 2019-05-05 19:42:04  |
|  5 |  AA |    1 | 2019-05-06 20:55:05  | NULL                 |

我尝试使用LEAD(LogTime) Over..,但无法指定type = 3的记录

请您帮忙。

这是我的SqlFiddle

2 个答案:

答案 0 :(得分:1)

您可以只使用join

SELECT t.*, t3.LogTime as LogTime3
FROM Trans t LEFT JOIN
     Trans t3
     ON t3.ref = t.ref and t3.TYPE = '3'
WHERE t.TYPE = '1'
ORDER BY t.id;

获取下一个时间的一种方法是使用OUTER APPLY

SELECT t.*, t3.LogTime as LogTime3
FROM Trans t OUTER APPLY
     (SELECT TOP (1) t3.*
      FROM Trans t3
      WHERE t3.ref = t.ref and
            t3.LogTime > t.LogTime and
            t3.TYPE = '3'
      ORDER BY t.LogTime ASC
     ) t3
WHERE t.TYPE = '1'
ORDER BY t.id;

或者,使用窗口函数,累积最小值似乎是最合适的:

SELECT t.*
FROM (SELECT t.*,
             MIN(CASE WHEN t.TYPE = '3' THEN t.LogTime END) OVER (PARTITION BY ref ORDER BY LogTime DESC) as LogTime3
      FROM Trans t 
     ) t
WHERE t.TYPE = '1'
ORDER BY t.id;

答案 1 :(得分:0)

通过使用子查询,我们也可以实现您的预​​期输出

SELECT DISTINCT
     O.ID,
     O.Ref,
     O.[Type],
     O.LogTime,
    (SELECT TOP 1 I.LogTime FROM LoginLogout I
     WHERE I.Ref = O.Ref
        AND I.[Type] = 3 
        AND I.LogTime > O.LogTime) AS LogTime_Type3 
FROM LoginLogout O
WHERE O.[Type] = 1