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