SQL 获取最后一次数字被设置为 1
SQL get the last time number was set to 1
我有一个类似于下面的 sql table。我想获取它最后一次从 0 更改为 1 以及最后一次更改回 0(下面突出显示的示例 ID)。
我试过的是:
select * from Table t1 join Table t2 on t1.id = t2.id join Table t3 on t1.id = t3.id
where t1.flag = 1 and t2.flag = 0 and t3.flag
group by t1.id
having min(t1.createdtime) between max(t2.createdtime) and min(t3.createdtime)
对于这个数据集,可以用lag()
把上一行的flag带进来,作为过滤条件,然后聚合:
select
id,
max(createdtime) createdtime,
flag
from (
select
t.*,
lag(flag) over(partition by id order by createdtime) lagflag
from mytable t
) t
where (flag = 0 and lagflag = 1) or (flag = 1 and lagflag = 0)
group by id, flag
您可以使用lag()
获取最近的标志。所以你可以过滤变化,即当(当前)标志和最近的标志根据需要相关时。要仅获取最新的更改,您可以按 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;
在 CTE
中使用 lag()
获取每一行的前一个标志,然后 NOT EXISTS
:
with cte as(
select *, lag(flag) over(partition by id order by createdtime) prevflag
from tablename
)
select c.id, c.createdtime, c.flag
from cte c
where c.flag <> c.prevflag
and not exists (
select 1 from cte
where id = c.id and flag = c.flag and prevflag = c.prevflag and createdtime > c.createdtime
)
order by c.createdtime
或:
with cte as(
select *, lag(flag) over(partition by id order by createdtime) prevflag
from tablename
)
select id, max(createdtime) createdtime, flag
from cte
where flag <> prevflag
group by id, flag
order by createdtime
参见demo。
结果:
> id | createdtime | flag
> -: | :------------------ | ---:
> 5 | 2019-11-02 14:30:00 | 1
> 5 | 2020-08-01 14:30:00 | 0
我有一个类似于下面的 sql table。我想获取它最后一次从 0 更改为 1 以及最后一次更改回 0(下面突出显示的示例 ID)。
我试过的是:
select * from Table t1 join Table t2 on t1.id = t2.id join Table t3 on t1.id = t3.id
where t1.flag = 1 and t2.flag = 0 and t3.flag
group by t1.id
having min(t1.createdtime) between max(t2.createdtime) and min(t3.createdtime)
对于这个数据集,可以用lag()
把上一行的flag带进来,作为过滤条件,然后聚合:
select
id,
max(createdtime) createdtime,
flag
from (
select
t.*,
lag(flag) over(partition by id order by createdtime) lagflag
from mytable t
) t
where (flag = 0 and lagflag = 1) or (flag = 1 and lagflag = 0)
group by id, flag
您可以使用lag()
获取最近的标志。所以你可以过滤变化,即当(当前)标志和最近的标志根据需要相关时。要仅获取最新的更改,您可以按 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;
在 CTE
中使用 lag()
获取每一行的前一个标志,然后 NOT EXISTS
:
with cte as(
select *, lag(flag) over(partition by id order by createdtime) prevflag
from tablename
)
select c.id, c.createdtime, c.flag
from cte c
where c.flag <> c.prevflag
and not exists (
select 1 from cte
where id = c.id and flag = c.flag and prevflag = c.prevflag and createdtime > c.createdtime
)
order by c.createdtime
或:
with cte as(
select *, lag(flag) over(partition by id order by createdtime) prevflag
from tablename
)
select id, max(createdtime) createdtime, flag
from cte
where flag <> prevflag
group by id, flag
order by createdtime
参见demo。
结果:
> id | createdtime | flag
> -: | :------------------ | ---:
> 5 | 2019-11-02 14:30:00 | 1
> 5 | 2020-08-01 14:30:00 | 0