使用 window 函数计算移动 sum/average 时的动态行范围(SQL 服务器)
Dynamic row range when calculating moving sum/average using window functions (SQL Server)
我目前正在编写一个示例脚本,它允许我计算前两行和当前行的总和。但是,我想将数字“2”作为变量。我试过声明一个变量,或直接在查询中进行强制转换,但总是弹出语法错误。有可能的解决方案吗?
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SELECT
SUM(myValue) OVER (ORDER BY myValue
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
FROM @myTable
DECLARE @test VARCHAR = 1
DECLARE @sqlCommand VARCHAR(1000)
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SET @sqlCommand = 'SELECT SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN ' + @test + ' PRECEDING AND CURRENT ROW)
FROM #temp'
EXEC (@sqlCommand)
你可以尝试这样不使用动态的东西SQL。
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
DECLARE @prev_records INT = 2
;WITH CTE as
(
SELECT ROW_NUMBER() OVER(ORDER BY myValue) rn,myValue FROM @myTable
)
SELECT (SELECT SUM(myValue) FROM CTE t2 WHERE t2.rn BETWEEN (t1.rn - @prev_records) AND t1.rn )
FROM CTE t1
SUM(myValue) OVER()
是最佳选择,但它不允许您使用变量传递前 N 行。
如果范围变量的离散度不是很高,可以使用简单的CASE
语句在计算之间切换
DECLARE @myTable TABLE (myValue INT)
-- let's say it could be between 1 and 10
DECLARE @range int = 3;
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SELECT
CASE @range
WHEN 1 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
WHEN 2 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
WHEN 3 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
WHEN 4 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
WHEN 5 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)
WHEN 6 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
WHEN 7 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
WHEN 8 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 8 PRECEDING AND CURRENT ROW)
WHEN 9 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
WHEN 10 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)
END
FROM @myTable
我目前正在编写一个示例脚本,它允许我计算前两行和当前行的总和。但是,我想将数字“2”作为变量。我试过声明一个变量,或直接在查询中进行强制转换,但总是弹出语法错误。有可能的解决方案吗?
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SELECT
SUM(myValue) OVER (ORDER BY myValue
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
FROM @myTable
DECLARE @test VARCHAR = 1
DECLARE @sqlCommand VARCHAR(1000)
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SET @sqlCommand = 'SELECT SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN ' + @test + ' PRECEDING AND CURRENT ROW)
FROM #temp'
EXEC (@sqlCommand)
你可以尝试这样不使用动态的东西SQL。
DECLARE @myTable TABLE (myValue INT)
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
DECLARE @prev_records INT = 2
;WITH CTE as
(
SELECT ROW_NUMBER() OVER(ORDER BY myValue) rn,myValue FROM @myTable
)
SELECT (SELECT SUM(myValue) FROM CTE t2 WHERE t2.rn BETWEEN (t1.rn - @prev_records) AND t1.rn )
FROM CTE t1
SUM(myValue) OVER()
是最佳选择,但它不允许您使用变量传递前 N 行。
如果范围变量的离散度不是很高,可以使用简单的CASE
语句在计算之间切换
DECLARE @myTable TABLE (myValue INT)
-- let's say it could be between 1 and 10
DECLARE @range int = 3;
INSERT INTO @myTable ( myValue ) VALUES ( 5)
INSERT INTO @myTable ( myValue ) VALUES ( 6)
INSERT INTO @myTable ( myValue ) VALUES ( 7)
INSERT INTO @myTable ( myValue ) VALUES ( 8)
INSERT INTO @myTable ( myValue ) VALUES ( 9)
INSERT INTO @myTable ( myValue ) VALUES ( 10)
SELECT
CASE @range
WHEN 1 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
WHEN 2 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
WHEN 3 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
WHEN 4 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
WHEN 5 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)
WHEN 6 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
WHEN 7 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
WHEN 8 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 8 PRECEDING AND CURRENT ROW)
WHEN 9 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
WHEN 10 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)
END
FROM @myTable