mysql组通过组织结果

时间:2013-04-25 16:36:58

标签: mysql group-by

首先,我不知道我是否正确地命名了这个问题,但我不知道如何正确地调用它:/

我有这个问题:

SELECT COUNT( id ), jumper, `date` FROM demosdb WHERE jumperid = '1053' GROUP BY `date`
ORDER BY  `COUNT(id)` DESC

基本上demosdb是:

id (int), jumperid (int), date (int (basically contains timestamp))

到目前为止,这么好。但是,某些记录之间存在细微差别(我使用自动脚本进行更新,有时它会设置时间+/- 5s,例如该查询的结果:

COUNT(id)   date
10  1318763642
10  1318763643
10  1318763639
9   1318763641
9   1318763637
8   1318763640
8   1366200434

你可以看到第一行几乎有相同的时间,但是5s不同(37到42)。 100%确定+/- 60s(甚至更多)是同一件事的一部分,所以我想基本上对所有时间戳进行分组,这些时间戳不是1234567890而是12345678%。这可能只用mysql,还是我应该依赖php?

3 个答案:

答案 0 :(得分:1)

SQL中的分组完全依赖于相同的值,而不是接近或类似。您可以通过date/60分组将分块组合在一起来解决这个问题,但是你仍然会遇到一个阈值问题(第60秒的某些内容与第一秒的内容不同。下一分钟)。因此,我肯定建议在PHP中使用更智能的算法进行此操作,比较所有行并在与前一行间隔超过10秒或20秒时关闭块。

话虽如此,您的查询仍然存在问题。使用GROUP BY时,所有未分组的列都应具有聚合函数(例如maxavg),以告知DBMS 如何对它们进行分组。在您的情况下,您没有为列jumper执行此操作,因此它基本上包含随机结果(尽管通常看似合乎逻辑)。 MySQL是历史上唯一允许这样做的DBMS,而在所有其他数据库服务器中它是一个致命的查询错误。 MySQL现在支持严格模式,并认为它是一个错误,并且肯定会假设此行为在将来成为默认行为。因此,您现在应该更改它以防止将来发生破坏。

这样的事情会起作用:

$threshold = 60;
$results = [];
$block = 0;
while($row = mysql_fetch_object($query))
{
  if($row->date - $block > $threshold)
    $block = $row->date;
  $results[$block] += $row->count; 
}

(请原谅我使用弃用的mysql_命令,这对于快速伪代码来说是最简单的)

答案 1 :(得分:1)

您可以使用ROUND和负舍入值执行某些操作,该舍入值将舍入到小数的左侧而不是右侧。例如,如果您使用ROUND(date, -1)

,结果中的日期将如下所示
date        round(date, -1)
----------  ---------------
1318763642  1318763640
1318763643  1318763640
1318763639  1318763640
1318763641  1318763640
1318763637  1318763640
1318763640  1318763640
1366200434  1366200430

答案 2 :(得分:0)

接受附近突出显示的潜在缺陷,替代解决方案可能看起来像这样......

SELECT FLOOR(date/60)*60 dt
     , COUNT(DISTINCT jumperid) ttl 
  FROM jumpers 
 GROUP 
    BY dt;
相关问题