sql - SQL Server 使用以前的值更新列
问题描述
我正在尝试在表格列中制定过滤器。表A有3列spare_qty(起ID的作用),alt(高度,要过滤的Value),Alt_derivative(需要的Filtered_Value)。该表包含大约一百万行。我的目的是用公式填充 X 行的 Alt_derivative 列:Filtered_Value(X) = 0.9*Filtered_Value(X-1) + 0.1 * Value。该函数本质上可以平滑数据而不会滞后,就像窗口函数一样。事实证明,这不是一项微不足道的任务。
- 更新表列不允许使用函数超前或滞后。自引用都不成功。排序顺序被忽略。
- 游标的实现需要花费数小时。它似乎执行 NxN 行计算。此外,即使应考虑排序顺序,更新也会忽略该顺序。脚本是:
DECLARE @spare_qty bigint =0, @alt float = 0, @alt_derivative float =0
DECLARE TRX_Line CURSOR FOR
SELECT spare_qty1, alt, Alt_Derivative FROM [Incremental_Staging] order by ID asc;
OPEN TRX_Line
FETCH NEXT FROM TRX_Line INTO @ID, @value, @filtered_value
WHILE @@FETCH_STATUS = 0
BEGIN
update [Incremental_Staging]
SET
@alt = alt,
@alt_derivative = 0.1*@alt+ 0.9* @alt_derivative
where spare_qty1=@spare_qty1
FETCH NEXT FROM TRX_Line INTO @ID, @value, @filtered_value
end
close TRX_Line;
Deallocate TRX_Line;
- CTE 不尊重排序顺序。
坦率地说,我尝试了很多方法,只是为了遇到死胡同。这么简单的excel之类的事情有可能做不出来吗?我错过了什么吗?任何帮助,将不胜感激。
解决方案
评论太长了。
Filtered_Value(X) = 0.9*Filtered_Value(X-1) + 0.1 * 值
这不仅仅是一个滞后。这是指数平滑。在 SQL 中,有两种基本方法。
- 算术,它本质上是使用数学函数实现一个乘积聚合函数。
- 递归 CTE。
两者都不适合您的用例。第一个将在 1,000,000 行上出现问题。由于浮点数(或定点数)的舍入,会累积一些错误。并且该错误在 1,000,000 行上可能很明显。
第二个会起作用,但可能太慢了。
您可以检查返回值需要多长时间:
with i as (
select i.*, row_number() over (order by i) as seqnum
from incremental_staging i
),
cte as (
select seqnum, id, value, value as filter_value
from i
where seqnum = 1
union all
select i.seqnum, i.id, i.value, cte.filter_value * 0.9 + 0.1 * i.value
from cte join
i
on i.seqnum = cte.seqnum + 1
)
select *
from cte
option (maxrecursion 0);
递归 CTE(在这种情况下)可以处理几十或几百行。这可能是可以容忍的低几千。但是一百万行,它可能会很慢(尽管我想比游标快)。您可以使用它进行更新,方法是:
update incremental_staging
set filter_value = cte.filter_value
from cte
where cte.id = incremental_staging.id;
推荐阅读
- python - Matplotlib 不知从何处绘制未定义的图
- python - 通过引发 404 来保护页面
- javascript - mongodb - 聚合游标计数
- python - 如何使用函数更改返回函数/更改变量?
- java - 嵌套的 LinearLayouts LayoutTransition 动画在子移除时跳转
- dart - 如何从语言代码中获取语言的全名?(例如:从 'en' 到 'English')
- c# - 缺少使用 NUnit 3.12 的 TestCase 属性...?
- ruby - 当块有两个参数时,Ruby Array#map 的行为如何?
- android - Android Studio 错误模拟器:dsound:警告:语音未捕获 api 28 模拟器不起作用
- r - 使用 lapply 基于多个条件和子集创建新变量