0

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

我有这个查询:

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

您可以看到第一行的时间几乎相同,但相差 5 秒(37 到 42)。100% 确定 +/-60s(甚至更多)是同一事物的一部分,所以我想基本上将所有不是1234567890but的时间戳分组12345678%。仅使用 mysql 是否可行,还是应该依赖 php?

4

3 回答 3

1

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

话虽如此,您的查询被窃听了。当使用GROUP BY所有未分组的列时,应该有一个聚合函数(例如maxavg)来告诉 DBMS如何对它们进行分组。在您的情况下,您没有为 column 执行此操作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_的命令,这是快速伪代码最简单的方法)

于 2013-04-25T16:42:47.527 回答
1

您可以使用ROUND负舍入值来执行某些操作,该舍入值将舍入到小数点的左侧而不是右侧。例如,如果您使用,结果中的日期将如下所示ROUND(date, -1)

date        round(date, -1)
----------  ---------------
1318763642  1318763640
1318763643  1318763640
1318763639  1318763640
1318763641  1318763640
1318763637  1318763640
1318763640  1318763640
1366200434  1366200430
于 2013-04-25T16:43:30.303 回答
0

接受附近突出显示的潜在缺陷,替代解决方案可能如下所示......

SELECT FLOOR(date/60)*60 dt
     , COUNT(DISTINCT jumperid) ttl 
  FROM jumpers 
 GROUP 
    BY dt;
于 2013-05-06T10:24:43.883 回答