我有一个查询结果集。让我们说它包含100行,有2列。我想要第三个计算列作为最后10行的平均值。像这样:
Hours Pay Last10Avg
--------------------------
10 1
20 2
30 3
40 4
50 5
60 6
70 7
80 8
90 9
100 10 (550/55)= 10
110 11
...
200 20 (1550/155) = 10
因此,对于每10行,我希望基本上获得平均值。我的意思是1到10得到平均值。 11到20平均。我如何得到它(这个例子中每10行的价值' 10')
其他信息:
550 = 10+20+..100
55 = 1+2+..10
1550 = 110+120+...200
155 = 10+11+...20
答案 0 :(得分:4)
这就是范围分区的作用。如果您使用的是SQL Server 2012或更高版本,则可以执行以下操作:
select hours, pay,
(sum(hours) over (order by hours range between 9 preceding and current row) /
sum(pay) over (order by hours range between 9 preceding and current row)
) as thirdcol
from table t;
这会将移动平均线放在每一行上,因此它与问题的格式不完全相同,但似乎更有用。
答案 1 :(得分:1)
您可以按FLOOR(ROWNUMBER/10)
对数据进行分区,以计算平均值。
示例查询:
SELECT
T.Hours,
T.Pay,
-- Use case to count avg only for 1 out of 10 rows
CASE WHEN Idx % 10 = 0 THEN AVG(Hours/Pay)
OVER (PARTITION BY FLOOR((Idx-1)/10)) ELSE NULL END Avg
FROM (
SELECT
T.Hours,
T.Pay,
-- In order by specify order you need, use (SELECT 0) to keep db order
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) Idx
FROM [YourTable] T
) T
答案 2 :(得分:0)
只是一个非2012年的解决方案。
DECLARE @PageSize INTEGER;
SET @PageSize = 10;
WITH cteRanked
AS
(
SELECT ROW_NUMBER() OVER (ORDER BY Hours) AS RID,
ROW_NUMBER() OVER (ORDER BY Hours) % @PageSize AS ModValue,
Hours,
Pay
FROM Table1
),
cteWindows
AS
(
SELECT r1.RID AS StartRID,
r2.RID AS EndRID
FROM cteRanked r1 INNER JOIN cteRanked r2
ON r1.RID = r2.RID - (@PageSize - 1)
WHERE r1.ModValue = 1
)
SELECT r.Hours,
r.Pay,
SUM(r2.Hours) / SUM(r2.Pay) AS Last10Avg
FROM cteRanked r LEFT JOIN cteWindows w
ON r.RID = w.EndRID
LEFT JOIN cteRanked r2
ON r2.RID BETWEEN w.StartRID AND w.EndRID
GROUP BY r.Hours,
r.Pay
ORDER BY r.Hours,
r.Pay;
答案 3 :(得分:0)
试试这个, 用于最后N(4)记录平均值
with cte (a,b) as
(
select sum(hours),sum(pay) from mytable
where Hours not in(
select top (
(select COUNT(*) from
mytable)-4
)Hours from mytable)
)
select a/b from cte;