获取SQL中每个X行的平均值

时间:2014-02-08 05:26:30

标签: mysql sql

我们说我有下表

+----+-------+
| Id | Value |
+----+-------+
|  1 |   2.0 |
|  2 |   8.0 |
|  3 |   3.0 |
|  4 |   9.0 |
|  5 |   1.0 |
|  6 |   4.0 |
|  7 |   2.5 |
|  8 |   6.5 |
+----+-------+

我想绘制这些值,但由于我的真实表有数千个值,我想到了每个X行的平均值。有没有办法让我这样做,即每行2或4行,如下所示:

2
+-----+------+
| 1-2 |  5.0 |
| 3-4 |  6.0 |
| 5-6 |  2.5 |
| 7-8 |  4.5 |
+-----+------+

4
+-----+------+
| 1-4 |  5.5 |
| 5-8 |  3.5 |
+-----+------+

另外,有没有办法根据表格中的总行数使这个X值动态化?有点像,如果我有1000行,平均值将根据每200行(1000/5)计算,但如果我有20,则根据每4行(20/5)计算它。

我知道如何以编程方式执行此操作,但有没有办法使用纯SQL?

编辑:我需要它来处理mysql。

4 个答案:

答案 0 :(得分:6)

根据您的DBMS,这样的事情会起作用:

SELECT
   ChunkStart = Min(Id),
   ChunkEnd = Max(Id),
   Value = Avg(Value)
FROM
   (
      SELECT
         Chunk = NTILE(5) OVER (ORDER BY Id),
         *
      FROM
         YourTable
   ) AS T
GROUP BY
   Chunk
ORDER BY 
   ChunkStart;

根据您的要求,无论有多少行,都会创建5个组或块。

如果您没有窗口功能,可以伪造它:

SELECT
   ChunkStart = Min(Id),
   ChunkEnd = Max(Id),
   Value = Avg(Value)
FROM
   YourTable
GROUP BY
   (Id - 1) / (((SELECT Count(*) FROM YourTable) + 4) / 5)
;

我在这里做了一些假设,比如Id从1开始并且没有间隙,如果事情没有均匀划分,你会希望最后一组太小而不是太大。我还假设整数除法会像在SQL Server中那样产生。

答案 1 :(得分:2)

您可以使用modulos运算符对表的每个第N行执行操作。此示例将获得每第10行的平均值:

select avg(Value) from some_table where id % 10 = 0;

然后,您可以对表中的行进行计数,对其应用一些因子,并将该值用作动态区间:

select avg(Value) from some_table where id % (select round(count(*)/1000) from some_table) = 0;

您需要根据表格中的实际行数确定最佳间隔。

编辑: 重读你的帖子我意识到这是每个第N行的平均值,而不是每个连续的N行。我不确定这是否足够,或者你是否特别需要连续平均值。

答案 2 :(得分:1)

查看NTILE函数(如四分位数,五分位数,十分位数,百分位数)。您可以使用它将数据均匀地分成多个桶 - 在您的情况下,您似乎想要五个。

然后您可以使用AVG计算每个桶的平均值。

NTILE在SQL-99中,因此大多数DBMS都应该拥有它。

答案 3 :(得分:0)

您可以尝试

CREATE TABLE #YourTable
(
    ID int
    ,[Value] float
)
INSERT #YourTable (ID, [Value]) VALUES
 (1,2.0)
,(2,8.0)
,(3,3.0)
,(4,9.0)
,(5,1.0)
,(6,4.0)
,(7,2.5)
,(8,6.5)


SELECT
    ID = MIN(ID) + '-' + MAX(ID)
    ,[Value] = AVG([Value])
FROM
(
    SELECT  
        GRP = ((ROW_NUMBER() OVER(ORDER BY ID) -1) / 2) + 1
        ,ID = CONVERT(VARCHAR(10), ID)
        ,[Value]
    FROM
        #YourTable
) GrpTable
GROUP BY 
    GRP

DROP TABLE #YourTable