如果它们关闭,如何对表中的值进行分组?

时间:2013-12-22 22:49:54

标签: mysql sql group-by

假设我将10定义为两个值之间足够接近的差异,我想要的是所有彼此足够接近的值的平均值(换句话说,按其接近程度分组)。所以,如果我有一个包含以下值的表:

+-------+
| value |
+-------+
|     1 |
|     1 |
|     2 |
|     4 |
|     2 |
|     1 |
|     4 |
|     3 |
|    22 |
|    23 |
|    24 |
|    22 |
|    20 |
|    19 |
|    89 |
|    88 |
|    86 |
+-------+

我想要一个可以输出以下结果的查询:

+---------+
| 2.2500  |
| 21.6667 |
| 87.6667 |
+---------+

2.2500将作为所有值的平均值产生,范围从1到4,因为它们相距10或更少。同样地,21.6667将是所有值的平均值,范围从19到24,而87.6667将是所有值的平均值,范围从86到89.

我指定的当前10的差异必须是可变的。

4 个答案:

答案 0 :(得分:1)

这不是那么糟糕。您希望在MySQL中实现lag()函数,以确定值是否是一组新行的开头。然后,您需要此值的累积总和来识别组。

代码看起来很痛苦,因为在MySQL中,您需要使用相关子查询和连接/聚合而不是ANSI标准函数来执行此操作,但这就是它的样子:

select min(value) as value_min, max(value) as value_max, avg(value) as value_avg
from (select t.value, count(*) as GroupId
      from table t join
           (select value
            from (select value,
                         (select max(value)
                          from table t2
                          where t2.value < t.value
                         ) as prevValue
                  from table t
                 ) t
            where value - prevvalue < 10
           ) GroupStarts
           on t.value >= GroupStarts.value
      group by t.value
     ) t
group by GroupId;

子查询GroupStarts正在查找断点,即与前一个值相差10或更多的值集。下一级使用连接/聚合来计算任何给定值之前的此类断点的数量。最外面的查询然后使用此GroupId进行聚合。

答案 1 :(得分:0)

使用字段的哈希值创建另一列。该字段将用于测试相等性。例如,使用字符串,您可以存储soundex。对于数字,您可以存储最接近的十倍

否则进行计算会慢得多。您也可以将表交叉连接到自身,并将两个字段的差异分组。 10

答案 2 :(得分:0)

我喜欢其他用户建议创建哈希列。加入自己具有指数效应,应该避免。

另一种可能性是使用/,例如选择avg(val),来自myTable组的val / 10由val / 10得到的值为0表示0-9,1表示10-19等

至少,它在SQL Server中工作

答案 3 :(得分:0)

首先,我会将整个结果导出到数组中。

之后,使用功能

function show(elements_to_agroup=4)
{
for (i = 0; i < count(array) ; i++)
{
sum = 0;    

if (i % elements_to_agroup)
    { 
    sum = sum / elements_to_agroup; 
    return sum;
    }    
else
    {
    sum =+ array[i];
    }
}
}