我有一张包含价格信息的表格。我需要选择每三行的最大值。实施例:
Table `daily_high`
____ _______
| ID | HIGH |
| 1 | 24.65 |
| 2 | 24.93 |
| 3 | 26.02 |
| 4 | 25.33 |
| 5 | 25.16 |
| 6 | 25.91 |
| 7 | 26.05 |
| 8 | 28.13 |
| 9 | 27.07 |
|____|_______|
Desired output to new table (ID will be auto-increment so don't assume an association exists between this ID 1 and the daily_high ID 1:
____ ___________
| ID | 3MaxHIGH |
|____|___________|
| 1 | 26.02 |
| 2 | 25.91 |
| 3 | 28.13 |
|____|___________|
我想比较ID 1,2和3以确定它们之间的高值。然后,一旦我比较了1-3,我想继续进行4到6,然后是7到9等,直到我为表中包含的所有值(目前大约400,000个值)完成此操作。我编写了使用
的代码 SELECT max(HIGH) FROM daily_high as dh1 JOIN (SELECT max(HIGH) FROM daily_high WHERE id >= dh1 AND id < (dh1.id + 3))
这可行,但速度非常慢。我已经尝试使用SELECT语句来识别要显示的列值,这意味着在查询的SELECT和FROM部分之间。
我尝试使用JOIN将所有3行连接到同一个表上进行比较,但它也非常慢。慢了我的意思是在不到10秒的时间内收集20行的信息。这意味着查询已经在9.65879893303秒内分析了60行(20组3个)(我没有这样做,我使用microtime()来计算它。
对于比我更快的代码,任何人都有任何建议吗?
请记住,我的实际表格与上面发布的表格不同,但概念是相同的。
感谢您的帮助。
答案 0 :(得分:1)
如果您持续识别,则可以进行此操作
SELECT floor(id/3) as range, max(HIGH) FROM daily_high GROUP BY range;
答案 1 :(得分:0)
为什么不使用DIV
运算符对聚合进行分组:
SELECT (id-1) DIV 3 + 1 AS ID, MAX(high) AS 3MaxHIGH
FROM daily_high
GROUP BY (id-1) DIV 3
此查询提供相同的结果。
ID 3MaxHIGH
1 26.02
2 25.91
3 28.13
我无法运行您的查询,我相信这个更快。
UPD :为确保您拥有有效范围的群组,请使用此查询:
select id, high, (id-1) div 3 + 1 from daily_high
结果:
id high (id-1) div 3 + 1
1 24.65 1
2 24.93 1
3 26.02 1
4 25.33 2
5 25.16 2
6 25.91 2
7 26.05 3
8 28.13 3
9 27.07 3
答案 2 :(得分:0)
富勒以一个例子回答。以下代码将执行我认为您想要的操作。
SELECT FLOOR((row - 1) / 3), MAX(Sub1.high)
FROM (SELECT @row := @row + 1 as row, daily_high.*
FROM daily_high, (SELECT @row := 0) r) Sub1
GROUP BY FLOOR((row - 1) / 3)
ORDER BY Sub1.ID
答案 3 :(得分:0)
以下查询在测试表上为我工作。也许不是最好的,但其他解决方案在我的测试台上失败了。
这确实要求ID是顺序的。另外一定要把一个索引放在High以及速度上。
SELECT FLOOR(T1.Id/3)+1 AS Id, ROUND(GREATEST(T1.High, T2.High, T3.High),2) AS High FROM `daily_high` T1, `daily_high` T2, `daily_high` T3
WHERE T2.Id=T1.Id+1
AND T3.Id=T2.Id+1
AND MOD(T1.Id, 3)=1
答案 4 :(得分:0)
logic: if(id is divisible by 3, id/3-1, id/3)
select if(mod(id,3) = 0,floor(id/3)-1,floor(id/3)) as group_by_col , max(HIGH)
FROM daily_high GROUP BY group_by_col;