查询以查找最近30分钟内创建的记录,然后查找最近1小时内创建的记录

时间:2015-09-20 08:45:45

标签: mysql sql performance

我有一个项目数据库,我需要找到在过去30分钟内创建的项目,并希望按照category订购它们,然后我想要在过去1中创建的项目小时但我想排除以前找到的项目,我想再次通过category订购它们。

我正在使用的当前方法是使用union。我不太确定这是不是最好的方法。我内心的一些东西告诉我有更好的方法来做到这一点,只是不知道如何。

这是一组示例数据和查询

id    category_id    created_at
1     1              10 mins ago
2     1              12 mins ago
3     2              10 mins ago
4     2              14 mins ago
5     1              40 mins ago
6     2              43 mins ago
7     1              34 mins ago

(select * from items where created_at >= NOW() - 30 mins order by category_id) union (select * from items where created_at >= NOW() - 60 mins and created_at < NOW() - 30 mins order by category_id)

示例查询显然在语法上不正确。

创建表格 create table items (id int(11), category_id int(11), created_at datetime);

输出:

id    category_id    created_at
1     1              10 mins ago
2     1              12 mins ago
3     2              10 mins ago
4     2              14 mins ago
5     1              40 mins ago
7     1              43 mins ago
6     2              34 mins ago

1 个答案:

答案 0 :(得分:0)

你的想法是正确的,但正确的语法是:

SELECT "last 30 minutes" as t, category_id, count(*) as cnt
FROM items
WHERE created_at >= NOW() - INTERVAL 30 MINUTE
GROUP BY category_id
UNION ALL
SELECT "last 1 hour" as t, category_id, count(*) as cnt
FROM items
WHERE
  created_at < NOW() - INTERVAL 30 MINUTE
  AND created_at >= NOW() - INTERVAL 60 MINUTE
GROUP BY category_id

...等...

此查询将计算过去30分钟内的事件,按category_id分组,然后计算过去一小时但不是最近30分钟内的所有事件。

UNION ALL

在此上下文中优于UNION,因为UNION将返回唯一的行。

修改

根据您更新的问题,我认为您正在寻找:

SELECT items.*
FROM items
WHERE created_at>=NOW() - INTERVAL 60 MINUTE
ORDER BY
  (created_at >= NOW() - INTERVAL 30 MINUTE) DESC,
  category_id

如果你有更多的间隔,那么你可以使用它:

SELECT items.*
FROM items
WHERE created_at>=NOW() - INTERVAL 120 MINUTE
ORDER BY
  (created_at >= NOW() - INTERVAL 30 MINUTE) DESC,
  (created_at >= NOW() - INTERVAL 60 MINUTE) DESC,
  category_id