获取每个唯一 ID 的列的最后一次更改值的第一次出现
get first occurrence of last changed value of a column for each unique id
如何获取“sval”列最后一次更改值的第一次出现?
对于 id = 22,71 是最后更改的值,因此想要获取第一次出现的 71。
id = 25 的方法相同,74 是最后更改的值,因此想要获取 74 的第一次出现。
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=c980809154d41f2accc9f14d569b48f1
数据:
在上图中,我想获取突出显示的行。
尝试:
with LastValue as (
select t.sval
from test t
order by t.date desc
limit 1
)
select t.*
from test t
where t.sval = (select sval from LastValue)
and t.date > (select max(tt.date) from test tt where tt.sval <> (select sval from LastValue))
order by t.date asc
limit 1;
实际上问题陈述是我不希望 sval 第一次出现时分组,而是我想要最后更改的 sval 所以我们的示例在突出显示的行之后应该是 returns for ids (22,25).
执行此操作的一种方法是使用 lag()
检查差异,然后选择存在差异的最后一点:
select t.*
from (select t.*,
row_number() over (partition by id order by date desc) as seqnum
from (select t.*,
lag(sval) over (partition by id order by date) as prev_sval
from test t
) t
where prev_sval is null or prev_sval <> sval
) t
where seqnum = 1;
非常重要:这 returns 上次发生变化 即使值 returns 为 id
[=18 的已见值=].我就是这样解释你的问题的。
WITH
cte1 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` DESC) rn1,
ROW_NUMBER() OVER (PARTITION BY id, sval ORDER BY `date` DESC) rn2
FROM test ),
cte2 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` ASC) rn3
FROM cte1
WHERE rn1 = rn2 )
SELECT id, date, sval
FROM cte2
WHERE rn3 = 1;
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=a25569690e4b35a55b0bee13856eb724
如何获取“sval”列最后一次更改值的第一次出现? 对于 id = 22,71 是最后更改的值,因此想要获取第一次出现的 71。 id = 25 的方法相同,74 是最后更改的值,因此想要获取 74 的第一次出现。
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=c980809154d41f2accc9f14d569b48f1
数据:
在上图中,我想获取突出显示的行。
尝试:
with LastValue as (
select t.sval
from test t
order by t.date desc
limit 1
)
select t.*
from test t
where t.sval = (select sval from LastValue)
and t.date > (select max(tt.date) from test tt where tt.sval <> (select sval from LastValue))
order by t.date asc
limit 1;
实际上问题陈述是我不希望 sval 第一次出现时分组,而是我想要最后更改的 sval 所以我们的示例在突出显示的行之后应该是 returns for ids (22,25).
执行此操作的一种方法是使用 lag()
检查差异,然后选择存在差异的最后一点:
select t.*
from (select t.*,
row_number() over (partition by id order by date desc) as seqnum
from (select t.*,
lag(sval) over (partition by id order by date) as prev_sval
from test t
) t
where prev_sval is null or prev_sval <> sval
) t
where seqnum = 1;
非常重要:这 returns 上次发生变化 即使值 returns 为 id
[=18 的已见值=].我就是这样解释你的问题的。
WITH
cte1 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` DESC) rn1,
ROW_NUMBER() OVER (PARTITION BY id, sval ORDER BY `date` DESC) rn2
FROM test ),
cte2 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` ASC) rn3
FROM cte1
WHERE rn1 = rn2 )
SELECT id, date, sval
FROM cte2
WHERE rn3 = 1;
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=a25569690e4b35a55b0bee13856eb724