我们说我有下表
+----+-------+
| 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。答案 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