You can use lag()
to get the recent flag. So you can filter for changes, i.e. when the (current) flag and the recent flag relate as desired. To get only the most recent of the changes you can filter by row_number()
.
SELECT z.id,
z.createdtime,
z.flag
FROM (SELECT y.id,
y.createdtime,
y.flag FROM (SELECT x.id,
x.createdtime,
x.flag,
row_number() OVER (PARTITION BY x.id
ORDER BY x.createdtime DESC) rn
FROM (SELECT t.id,
t.createdtime,
t.flag,
lag(t.flag) OVER (PARTITION BY t.id
ORDER BY createdtime) recentflag
FROM elbat t) x
WHERE x.flag = 0
AND x.recentflag = 1) y
WHERE y.rn = 1
UNION ALL
SELECT y.id,
y.createdtime,
y.flag FROM (SELECT x.id,
x.createdtime,
x.flag,
row_number() OVER (PARTITION BY x.id
ORDER BY x.createdtime DESC) rn
FROM (SELECT t.id,
t.createdtime,
t.flag,
lag(t.flag) OVER (PARTITION BY t.id
ORDER BY createdtime) recentflag
FROM elbat t) x
WHERE x.flag = 1
AND x.recentflag = 0) y
WHERE y.rn = 1) z
ORDER BY z.createdtime DESC;