MySQL:范围内的GROUP BY

时间:2014-07-09 20:12:01

标签: php mysql sql

我的桌子上有这样的分数:

  score  |  user
 -------------------
     2   |  Mark
     4   |  Alex
     3   |  John
     2   |  Elliot
    10   |  Joe
     5   |  Dude

这张桌子实际上是巨大的,真正的分数从1到25。

我需要这个:

  range   |  counts
 -------------------
   1-2    |  2
   3-4    |  2
   5-6    |  1
   7-8    |  0
   9-10   |  1

我找到了一些MySQL解决方案,但它们看起来相当复杂,有些甚至建议UNION,但性能非常重要。如上所述,表格很大。

所以我想为什么你不能简单地得到这样的查询:

SELECT COUNT(*) as counts FROM score_table GROUP BY score

我明白了:

  score  |  counts
 -------------------
    1    |   0
    2    |   2
    3    |   1
    4    |   1
    5    |   1
    6    |   0
    7    |   0
    8    |   0
    9    |   0
   10    |   1

然后使用PHP,总结特定范围的分数? 这对性能来说更糟糕还是有一个我想念的简单解决方案?

或者您甚至可以制作JavaScript解决方案......

5 个答案:

答案 0 :(得分:3)

您的解决方案:

SELECT score, COUNT(*) as counts
FROM score_table
GROUP BY score
ORDER BY score;

但是,这不会为计数返回0的值。假设您有所有分数的示例,那么完整的分数列表不是问题。你只是没有得到零的数量。

你可以用以下的东西做你想做的事:

select (case when score between 1 and 2 then '1-2'
             when score between 3 and 4 then '3-4'
             . . .
        end) as scorerange, count(*) as count
from score_table
group by scorerange
order by min(score);

没有理由在php中进行额外的处理。这种类型的查询对于SQL来说非常典型。

编辑:

根据MySQL documentation,您可以在group by中使用列别名。这是确切的引用:

  

可以在查询选择列表中使用别名来为列a提供   不同的名字。您可以在GROUP BY,ORDER BY或HAVING中使用别名   条款引用专栏:

答案 1 :(得分:1)

选择     和(         案件            当得分在1和2之间时            然后......

答案 2 :(得分:1)

老实说,我不能告诉你这是否比传递更快" SELECT COUNT(*)作为计数FROM score_table GROUP BY得分"进入PHP并让PHP处理它...但它为您的设置增加了一定程度的灵活性。创建一个三栏表作为' group_ID','得分','范围'。在其中插入值以使您的分组正确

1,1,1-2

1,2,1-2

1,3,3-4

1,4,3-4

等...

在分数上加入它,按范围分组。添加了' group_ID'允许你设置组...也许让组1将其分成两组,让group_ID = 2为5组范围(或任何你想要的范围)。

我发现像这样的表使用速度非常快,需要很少的代码更改,如果你需要额外的分组或者如果分组发生变化,可以很容易地添加(如果你在代码中进行分组,整个案例部分需要重做以稍微改变分组。)

答案 3 :(得分:1)

如果你想要一个功能非常强大的简单解决方案,可以在你的表中添加一个额外的字段,并在其中为分数添加一个值,这样1和2的值为1,3和4就有2.你可以分组通过那个价值。只需插入分数即可添加额外字段。所以你的表看起来像这样:

score  |  user     |   range
--------------------------
   2   |  Mark     |   1
   4   |  Alex     |   2
   3   |  John     |   2
   2   |  Elliot   |   1
  10   |  Joe      |   5
   5   |  Dude     |   3

现在你可以做到:

select count(score),range from table group by range;

如果你选择了之前的应用程序,这总是更快。

通过插入执行此操作:

$scoreRange = 2;
$range = ceil($score/$scoreRange);

答案 4 :(得分:1)

这个怎么样:

select concat((score + (1 * (score mod 2)))-1,'-',(score + (1 * (score mod 2)))) as score, count(*) from TBL1 group by (score + (1 * (score mod 2)))

你可以看到它在这个小提琴中起作用:http://sqlfiddle.com/#!2/215839/6

输入

  score  |  user
 -------------------
     2   |  Mark
     4   |  Alex
     3   |  John
     2   |  Elliot
    10   |  Joe
     5   |  Dude

它产生了这个:

  range   |  counts
 -------------------
   1-2    |  2
   3-4    |  2
   5-6    |  1
   9-10   |  1