MySQL一个查询按组内的n行,最大值和最小值分组,可能吗?

时间:2017-11-29 18:36:26

标签: mysql sql group-by

我认为没有这样的问题。 我需要按n个记录对行进行分组,并获得该组的一些值。

我认为最好用图形示例来解释:

graphic description of the query I need

可以像这样进行查询吗?如果不是我的解决方案将创建一个脚本来创建另一个表,但我不喜欢重复的数据。

感谢!!!

5 个答案:

答案 0 :(得分:1)

set @counter=-1;
select xgroup,max(x) as mx, max(y) as my, avg(value3) as v3,
from
(
select (@counter := @counter +1) as counter, 
   @counter div 5 as xgroup,
   currency, datetime, value1, value2,
   case mod(@counter,5) when 0 then value1 else 00 end as x,
   case mod(@counter,5) when 4 then value2 else 00 end as y,
   mod(@counter,5) as xxx
FROM findata
) name1
group by xgroup;

答案 1 :(得分:1)

@jms有正确的方法,但在使用变量时必须非常小心:

  • 您不应在一个表达式中指定变量,然后在同一个select中的另一个表达式中引用它。
  • 要在最新版本的MySQL中工作,我建议在子查询中对数据进行排序。

此外,您还需要其他一些值:

select min(col1), min(col2),
       max(case when mod(rn, 5) = 0 then col3 end),
       max(col4), min(col5),
       max(case when mod(rn, 5) or rn = @rn then col6 end),
       max(case when mod(rn, 5) or rn = @rn then col7 end)
from (select (@rn := @rn + 1) as rn, t.*
      from (select t.*
            from t
            order by col1, col2
           ) t cross join
           (select @rn := -1) params
     ) t
group by (@rn div 5);

请注意,逻辑对于最后一个值来说有点神秘 - 这是考虑到可能没有正好5行的最终组。

答案 2 :(得分:1)

您需要一个看起来像的列(假设您要对每5行进行分组)

dummy_table
1
1
1
1
1
2
2
2
2
2
...

如果您使用

使用postgre sql,则可以使用generate_series()来完成此操作
select t1 from (select generate_series(1,x)) t1, (select generate_series(1,5)) t2;

您可以将x替换为(总行数/ 5),即100行,x = 20.如果您使用的是任何其他SQL平台,则可以相应地创建此虚拟表。

获得此dummy_table后,将其与您的表的row_number上的表连接,并使用dummy_table的t1列(而不是dummy_table的row_number)。访问行号的语法应该很简单。

With new column

加入后,按此t1列进行分组并执行所需的聚合。要在单个查询中执行此操作,您可以在内部查询中执行上述操作并在其外部执行聚合。希望这是有道理的。

答案 3 :(得分:0)

好的,谢谢你们所有人的回答,多亏了它,我找到了简单的解决方案。

我只需添加一个自动增量列,然后我可以按整数除以5对结果进行分组。

enter image description here

使用此查询:

SELECT id,
   symbol,
   datetime,
   open,
   MAX(high),
   MIN(low),
   SUBSTRING_INDEX( GROUP_CONCAT(CAST(close AS CHAR) ORDER BY datetime DESC), ',', 1 ) AS close 
FROM `table` 
GROUP BY (id-1) DIV 5

结果是:

enter image description here

谢谢!

答案 4 :(得分:0)

一种解决方案是引入一些用于对行进行分组以进行聚合操作的字段。

可以通过引入用户变量并分配允许对行进行分组的值来实现。例如,它可以是一个行计数器,除以分组的卡盘大小并四舍五入到最接近的上盖编号:

SET @counter=0;
SELECT CEIL((@counter:=@counter+1)/5) AS chunk, MAX(high), MIN(low) FROM `table` GROUP BY chunk;