Reputation: 1830
I have the following table:
| 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 |
I would like to list all rows with Type = 1 and to include the value of LogTime where Ref values are equal and Type =3
Something like this:
| 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 |
I tried to use LEAD(LogTime) Over..
but I were not able to specify the records with type=3
Can you please help.
Here is my SqlFiddle
Upvotes: 0
Views: 504
Reputation: 21
By using subquery also we can achieve your expected output
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
Upvotes: 0
Reputation: 1271151
You can just use 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;
One way to get the next time is to use 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;
Or, using window functions, a cumulative minimum seems the most appropriate:
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;
Upvotes: 1