2010-10-22 27 views
0

其实我甚至不知道如何调用这样的:P,但...非常复杂的集团通过由SQL命令/独特/限制

我有一个表,让我们把它称为“上传”

id owner date 
----------------------------- 
0  foo  20100101120000 
1  bar  20100101120300 
2  foo  20100101120400 
3  bar  20100101120600 
.. ..  .. 
6  foo  20100101120800 

现在,当I'ld做这样的事情:

SELECT id FROM uploads ORDER BY date DESC 

这将导致:

id owner date 
----------------------------- 
6  foo  20100101120800 
.. ..  .. 
3  bar  20100101120600 
2  foo  20100101120400 
1  bar  20100101120300 
0  foo  20100101120000 

问题:不错,但是,我想走得更远。因为现在,当你想建立一个时间表(而且我做了:P)时,你被'垃圾邮件'通过消息说foo和bar上传了一些东西。我想对它们进行分组,并在日期字段中返回时间限制为'500'的第一个结果。

什么样的SQL命令的,我需要的是会导致:

id owner date 
----------------------------- 
6  foo  20100101120800 
3  bar  20100101120600 
0  foo  20100101120000 

然后,在这之后,我可以为每个记录进行调用以获取在5分钟的时间内完成关联记录(这是id = 6的示例):

SELECT id FROM uploads WHERE date>=20100101120800-500 ORDER BY date DESC 

现在有人应该怎么做第一步吗? (如此限制/分组的结果)

(btw。我知道,当我想要使用这个,我应该将每个日期(YmdHis = 60)转换为Unix时间(= 100),但我不需要5分钟正好5分钟,它们可能会稍微减少一分钟...)

回答

1

我不太清楚你想要得到的结果,即使是你的例子。也许是一些四舍五入的组合。

SELECT max(id) max_id,owner, (ROUND(date/500)*500) date_interval, max(date) date 
FROM uploads GROUP BY date_interval,owner 

您可能想使用FLOOR或CEILING而不是ROUND,具体取决于您想要的。

+0

这正是我的意思。我现在使用“SELECT id FROM uploads GROUP BY ROUND(UNIX_TIMESTAMP(date)/ 3600),owner”。我使用3600,因为我认为1小时比5分钟更好。在Reinierpost提到“间隔”之后,我开始使用Google搜索到“MySQL Group By Interval”,我发现这个:http://forum.percona.com/index.php/t/748/,这非常有帮助! 无论如何,非常感谢Reinierpost,Symcbean和Brent! – elslooo 2010-10-22 16:25:27

1

标准SQL不处理间隔很好。 您将需要执行表的自连接以比较不同元组的日期。这样,你可以很容易地找到所有日期不超过500个元组的元组对。 但是,您真的想要将集合中的日期聚集在不超过500个集合中 - 并且根据我的理解,这些集合中不能用SQL表示。

你可以做的事情非常相似:将总时间间隔分成固定的500个单位范围,然后根据它们所在的时间间隔对表中的所有元组进行聚类。为此,首先需要一张表或查询结果与间隔的开始时间;可以使用表上的SQL查询和将时间戳“舍入”到其间隔中的开始时间或者计算其间隔序号的函数来创建。然后,作为第二步,您可以将该结果加入表中,根据其相应的开始时间对其时间戳进行分组。我无法提供SQL,因为它依赖于DBMS,而且我当然不能告诉你这是否是在您的情况下完成所需任务的最佳方式。

1

使用内联视图?例如像

SELECT u1.* 
FROM uploads u1, 
(SELECT date 
    FROM uploads u2 
    WHERE u2.owner='foo') datum_points 
WHERE u1.date BETWEEN datum_points.date 
    AND DATE_ADD(datum_points.date INTERVAL 5 MINUTES) 

应返回'foo'发出5分钟内发出的所有帖子。