gpt4 book ai didi

sql - 窗口函数 first_value 的意外行为

转载 作者:行者123 更新时间:2023-11-29 14:13:13 28 4
gpt4 key购买 nike

我有 2 列 - 订单号、值(value)。表值构造函数:

(1, null)
,(2, 5)
,(3, null)
,(4, null)
,(5, 2)
,(6, 1)

我需要得到

(1, 5) -- i.e. first nonnull Value if I go from current row and order by OrderNo
,(2, 5)
,(3, 2) -- i.e. first nonnull Value if I go from current row and order by OrderNo
,(4, 2) -- analogous
,(5, 2)
,(6, 1)

这是我认为应该有效的查询。

;with SourceTable as (
select *
from (values
(1, null)
,(2, 5)
,(3, null)
,(4, null)
,(5, 2)
,(6, 1)
) as T(OrderNo, Value)
)
select
*
,first_value(Value) over (
order by
case when Value is not null then 0 else 1 end
, OrderNo
rows between current row and unbounded following
) as X
from SourceTable
order by OrderNo

问题是它返回与 SourceTable 完全相同的结果集。我不明白为什么。例如,如果第一行被处理(OrderNo = 1),我希望 X 列返回 5,因为框架应该包括所有行(当前行和未绑定(bind)的后续行)并且它按值排序 - 首先是非空值,然后是 OrderNo。所以框架中的第一行应该是 OrderNo=2。显然它不是那样工作的,但我不明白为什么。

如果有人能解释第一帧是如何构建的,我们将不胜感激。我需要这个用于 SQL Server 和 Postgresql。

非常感谢

最佳答案

虽然可能比两个窗口函数更昂贵,但您可以在不使用数组的子查询的情况下执行此操作:

with SourceTable as (
select *
from (values (1, null),
(2, 5),
(3, null),
(4, null),
(5, 2),
(6, 1)
) T(OrderNo, Value)
)
select st.*,
(array_remove(array_agg(value) over (order by orderno rows between current row and unbounded following), null))[1] as x
from SourceTable st
order by OrderNo;

Here是 db<> fiddle 。

或者使用横向连接:

select st.*, st2.value
from SourceTable st left join lateral
(select st2.*
from SourceTable st2
where st2.value is not null and st2.orderno >= st.orderno
order by st2.orderno asc
limit 1
) st2
on 1=1
order by OrderNo;

如果源表上有正确的索引,从性能的角度来看,横向连接可能是最好的解决方案(我对横向连接在适当情况下的性能感到惊讶)。

关于sql - 窗口函数 first_value 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58418463/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com