首先,我不知道我是否正确地命名了这个问题,但我不知道如何正确地调用它:/
我有这个问题:
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?
答案 0 :(得分:1)
SQL中的分组完全依赖于相同的值,而不是接近或类似。您可以通过date/60
分组将分块组合在一起来解决这个问题,但是你仍然会遇到一个阈值问题(第60秒的某些内容与第一秒的内容不同。下一分钟)。因此,我肯定建议在PHP中使用更智能的算法进行此操作,比较所有行并在与前一行间隔超过10秒或20秒时关闭块。
话虽如此,您的查询仍然存在问题。使用GROUP BY
时,所有未分组的列都应具有聚合函数(例如max
或avg
),以告知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;