重置前根据增加的列值选择最后一行?
Posted
技术标签:
【中文标题】重置前根据增加的列值选择最后一行?【英文标题】:Select last rows based on increasing column value before reset? 【发布时间】:2021-08-31 07:17:02 【问题描述】:我尝试编写一个 (postgres) sql 查询,该查询返回特定数字列低于其前一个值之前的最后一行,用于多个 services
。
假设给定的数据如下所示:
service | captured | online_seconds
--------+----------+---------------
A | 01:10:00 | 500 <--
A | 01:08:00 | 100
A | 01:07:00 | 600 <--
A | 01:02:00 | 50
B | 01:09:00 | 400 <--
B | 01:06:00 | 200
B | 01:05:00 | 700 <--
预期的结果是:
service | captured | online_seconds
--------+----------+---------------
A | 01:10:00 | 500
A | 01:07:00 | 600
B | 01:09:00 | 400
B | 01:05:00 | 700
SQL 小提琴:https://www.db-fiddle.com/f/9jZiSLa5L9tCD7pmXwFiYW/1
到目前为止,我无法找到任何解决方案,如果可能的话,有什么想法可以实施吗?
【问题讨论】:
您不希望每个服务都有这个? IE。您希望在结果中包含最后一行,而不是服务 A 的最后一行,因为这之后是一行在线秒数增加的行,无论它是另一项服务。对吗? 结果应该是每个服务,正如您在预期结果中看到的那样。 A 和 B 完全独立。 啊,对不起,我的时间倒退了。表中的最后一行是捕获的第一行。所以我把这一切都搞混了。我已经更正了我的答案(即添加了缺少的分区子句)。 【参考方案1】:使用LEAD
查看下一行的数据:
select service, captured, online_seconds
from
(
select
service,
captured,
online_seconds,
lead(online_seconds) over (partition by service order by captured) as next_online_seconds
from mytable
) with_next_online_seconds
where next_online_seconds < online_seconds or next_online_seconds is null
order by captured;
【讨论】:
很好的答案,我不知道如何正确使用表分区功能,因为对我来说语法比普通查询更复杂。 是的,这些窗口函数的工作方式与其他表达式完全不同。图像您已完成整个选择并查看结果行。现在,对于该结果中的每一行,您都执行窗口函数 (LEAD OVER
)。 PARTITION BY
子句表示“仅查看具有相同服务的结果行”。 ORDER BY
表示查看行的顺序,LEAD
表示“给我该分区中的下一行和顺序(如果没有下一行,则为 null)。
这也是为什么你经常看到它们被包裹在另一个 Select 中的原因,因为过滤窗口结果为时已晚。【参考方案2】:
根据您的数据,您希望查看该服务的前一个值的值增加的位置。为此,请使用lag()
:
select t.*
from (select t.*,
lag(online_seconds) over (partition by service order by captured) as prev_online_seconds
from t
) t
where online_seconds > prev_online_seconds
【讨论】:
我不认为这是正确的......如果你有一个序列 100、200、300、400 你会显示 200、300、400 但我认为 OP 只想看到 400 @ChrisMaurer 。 . .您正在阅读我看不到的问题。 @ChrisMaurer 说的没错,我只想看到 400,即下降前的最大值。以上是关于重置前根据增加的列值选择最后一行?的主要内容,如果未能解决你的问题,请参考以下文章