仅在SQL Server中的最后n或10行的平均值

时间:2014-07-09 19:55:12

标签: sql-server average

SQL Image

我有一个查询结果集。让我们说它包含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

4 个答案:

答案 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

工作样本:http://sqlfiddle.com/#!6/d41d8/20091

答案 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;