Php MySQL:按范围分组

Php MySQL:按范围分组,php,mysql,sql,Php,Mysql,Sql,我有一张这样的分数表: score | user ------------------- 2 | Mark 4 | Alex 3 | John 2 | Elliot 10 | Joe 5 | Dude SELECT COUNT(*) as counts FROM score_table GROUP BY score score | user | range --------

我有一张这样的分数表:

  score  |  user
 -------------------
     2   |  Mark
     4   |  Alex
     3   |  John
     2   |  Elliot
    10   |  Joe
     5   |  Dude
SELECT COUNT(*) as counts FROM score_table GROUP BY score
score  |  user     |   range
--------------------------
   2   |  Mark     |   1
   4   |  Alex     |   2
   3   |  John     |   2
   2   |  Elliot   |   1
  10   |  Joe      |   5
   5   |  Dude     |   3
这张表实际上是巨大的,实际分数从1分到25分

我需要这个:

  range   |  counts
 -------------------
   1-2    |  2
   3-4    |  2
   5-6    |  1
   7-8    |  0
   9-10   |  1
我已经找到了一些MySQL解决方案,但它们似乎相当复杂,其中一些甚至建议使用UNION,但性能非常重要。如前所述,这张桌子很大

所以我想你为什么不简单地提出这样一个问题:

  score  |  user
 -------------------
     2   |  Mark
     4   |  Alex
     3   |  John
     2   |  Elliot
    10   |  Joe
     5   |  Dude
SELECT COUNT(*) as counts FROM score_table GROUP BY score
score  |  user     |   range
--------------------------
   2   |  Mark     |   1
   4   |  Alex     |   2
   3   |  John     |   2
   2   |  Elliot   |   1
  10   |  Joe      |   5
   5   |  Dude     |   3
我明白了:

  score  |  counts
 -------------------
    1    |   0
    2    |   2
    3    |   1
    4    |   1
    5    |   1
    6    |   0
    7    |   0
    8    |   0
    9    |   0
   10    |   1
然后用PHP计算特定范围的分数总和? 这对性能来说更糟糕,还是我缺少了一个简单的解决方案

或者你甚至可以制作一个JavaScript解决方案…

选择 总和 案例 当分数在1到2之间时 然后…

您的解决方案:

SELECT score, COUNT(*) as counts
FROM score_table
GROUP BY score
ORDER BY score;
但是,这不会为count返回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来说非常典型

编辑:

根据,可以在group by中使用列别名。以下是准确的报价:

可以在查询选择列表中使用别名为列指定名称 不同的名字。您可以在GROUP BY、ORDER BY或HAVING中使用别名 参考本栏的条款:


老实说,我无法告诉您这是否比将SELECT COUNT*as counts从score_表GROUP BY score传递到PHP并让PHP处理更快……但它为您的设置增加了一定程度的灵活性。创建一个三列表格,分别为“组ID”、“分数”和“范围”。在其中插入值以正确分组

1,1,1-2

1,2,1-2

1,3,3-4

1,4,3-4

等等

按分数加入,按范围分组。“group_ID”的添加允许您设置组…可能让group 1将其分成两个组,并让group_ID=2为5集范围或任何您想要的范围


我发现这样的表格使用速度非常快,只需要很少的代码更改,如果您需要额外的分组,或者如果分组在代码中进行分组时发生更改,则可以很容易地添加到表格中,整个案例部分需要重新做一次,以稍微更改分组。

如果您想要一个功能强大的简单解决方案,在您的表中添加一个额外字段,并在其中为分数添加一个值,以便1和2的值为1,3和4的值为2。有了它,您可以根据该值进行分组。只有通过插入分数,您才能添加一个额外的字段。因此,您的表如下所示:

  score  |  user
 -------------------
     2   |  Mark
     4   |  Alex
     3   |  John
     2   |  Elliot
    10   |  Joe
     5   |  Dude
SELECT COUNT(*) as counts FROM score_table GROUP BY score
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);
这个怎么样:

选择concatscore+1*分数模2-1,“-”,分数+1*分数模2作为分数,按分数+1*分数模2从TBL1组中计数*

您可以看到它在这把小提琴中工作:

输入

  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

对于像demo-d这样的小结果集,任何一种解决方案都可能是相同的,因为您进入了数千行,MySQL解决方案将是相同的better@Cheruvian事实上,这张桌子很大。但是分数只有1到25分,我无法想象这会有多大的不同。我猜MySQL版本会稍微快一点,但我建议您对每个版本进行基准测试。@yoshi您的范围大小相同还是不同?@VMai范围大小相同。此解决方案不太优雅和灵活。现在,您必须为每个分数范围创建一个案例!而且,这真的比PHP解决方案快吗?在PHP解决方案中,我只对特定范围的分数进行求和?@arjan,所以最好不要只是批评。@yoshi,这取决于数据集的大小。尺寸越大,我在RDBMS上的位置就越多。在大多数情况下,使用这样的用例需要几秒钟的时间,才能在数百万行上完成DB。我会挑战大多数人,让他们更快地进行简单的数据操作,尤其是在数据集越来越大的情况下。还请记住,您必须收回原始数据,这意味着更多的网络流量、更大的数据集等。成本不仅仅是时间,而且也是可以承受的。以我的拙见,是的。回顾一下Gordon的回答,他评论说这对于SQL来说是非常典型的;我也同意。我认为@user3741598的回答是合理的,尽管完整的回答不完整。如果这不是mysql,我会创建一个基于函数的索引,并在insert或update中设置该值。因此,在输入数据时,设置了值,这将是一个更简单的语句,如原始语句,但按基于函数的索引列进行分组。是否可以按scorerange别名进行分组@xQbert For MySQL::可以在查询选择列表中使用别名为列指定不同的名称。您可以使用GROUP BY、ORDER BY或HAVING子句中的别名来引用列:@GordonLinoff Ok,但我不确定它是否会返回零计数的任何值,beca 在PHP中使用时,我可以执行如下操作:Range1To2=0+CountForCore1+CountForCore2