我在 SQL Server 中有这个表:
日期 | var | 瓦尔 |
---|---|---|
2022-2-1 | A | 1.1 |
2022-3-1 | A | 2.3 |
2022-4-1 | A | 1.5 |
2022-5-1 | A | 1.7 |
2022-09-1 | B | 1.8 |
2022-10-1 | B | 1.9 |
2022-11-1 | B | 2.1 |
2022-12-1 | B | 2.22 |
我想按列 var 和日期进行分组,并实施扩展平均值和标准差,以创建一个标准差的上限和下限区间。最后,我希望检查 val 列中的每个条目(除了第一个条目)是否落入前一时间的间隔内(或滞后 1)。
如何在 SQL Server 中执行此操作?
我的尝试
-- Create the table
CREATE TABLE DataTable (
[date] DATE,
var CHAR(1),
val DECIMAL(4, 2)
);
-- Insert the data
INSERT INTO DataTable ([date], var, val)
VALUES
('2022-02-01', 'A', 1.1),
('2022-03-01', 'A', 2.3),
('2022-04-01', 'A', 1.5),
('2022-05-01', 'A', 1.7),
('2022-09-01', 'B', 1.8),
('2022-10-01', 'B', 1.9),
('2022-11-01', 'B', 2.1),
('2022-12-01', 'B', 2.22);
WITH DataWithStats AS (
SELECT
[date],
var,
val,
AVG(val) OVER (PARTITION BY var ORDER BY [date]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS exp_avg,
STDEV(val) OVER (PARTITION BY var ORDER BY [date]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS exp_std
FROM DataTable
)
SELECT
[date],
var,
exp_avg - 2 * exp_std AS lower,
val,
exp_avg + 2 * exp_std AS upper,
CASE
WHEN val < LAG(exp_avg - 2 * exp_std, 1) OVER (PARTITION BY var ORDER BY [date]) OR
val > LAG(exp_avg + 2 * exp_std, 1) OVER (PARTITION BY var ORDER BY [date])
THEN 'Warning'
ELSE 'ok'
END AS status
FROM DataWithStats;
我的尝试的问题是检查列没有正确评估检查。
https://sqlfiddle.com/sql-server/online-compiler?id=fe2e764f-9627-418f-bd08-dd13250b0dab
如果您认为查询结果中的“警告”状态不正确,因为 2.10 不是 超出显示的 1.62782795366962 - 2.23883804633038 范围,那么我认为问题是您显示的值不是用于计算状态的值。使用 LAG() 平均值和标准偏差值代替当前值。 2.10 值超出了测试使用的实际 1.7085786437627 - 1.9914213562373 范围。
结果是正确的(如编码所示),但演示文稿具有误导性。参见
这个数据库<>小提琴。