[英]MySQL: Get the minimum record for a user on a given day
我有一个事件表,每个事件都有一个负责人。 每天可能有多个此类事件,但是我需要在给定日期为每个用户的第一个查询记录。
例如,如果我有以下事件表:
+----------+-------------+---------------------+
| event_id | director_id | event_start |
+----------+-------------+---------------------+
| 1 | 111 | 2015-04-27 10:00:00 |
+----------+-------------+---------------------+
| 2 | 222 | 2015-04-27 11:00:00 |
+----------+-------------+---------------------+
| 3 | 333 | 2015-04-27 12:00:00 |
+----------+-------------+---------------------+
| 4 | 111 | 2015-04-27 13:00:00 |
+----------+-------------+---------------------+
| 5 | 222 | 2015-04-27 09:00:00 |
+----------+-------------+---------------------+
我想返回以下内容:
+----------+-------------+---------------------+
| event_id | director_id | event_start |
+----------+-------------+---------------------+
| 1 | 111 | 2015-04-27 10:00:00 |
+----------+-------------+---------------------+
| 5 | 222 | 2015-04-27 09:00:00 |
+----------+-------------+---------------------+
| 3 | 333 | 2015-04-27 12:00:00 |
+----------+-------------+---------------------+
我以为这样的查询会行得通,但事实证明MySQL在WHERE
子句中不支持MIN
( 简单的SQL查询提供了对group function的无效使用 ):
SELECT
event_id, director_id, MIN(event_start) AS event_start
FROM events
WHERE MIN(event_start) >= '2015-04-27 00:00:00'
AND MIN(event_start) < '2015-04-28 00:00:00'
GROUP BY director_id;
如何以最有效的方式做到这一点? 我的events
表可能很容易具有10,000-100,000条记录。
您可以通过与您的查询类似的查询来获得每天的最短活动时间:
SELECT director_id, date(event_start) as dte, MIN(event_start) AS event_start
FROM events e
GROUP BY director_id, date(event_start);
然后,您可以将其用作子查询以从行中获取所有其他信息:
select e.*
from events e join
(SELECT e.director_id, date(e.event_start) as dte, MIN(e.event_start) AS event_start
FROM events e
GROUP BY e.director_id, date(e.event_start)
) ee
on e.event_start = ee.event_start -- note, this has both the date and time;
如果要将结果限制为一天,可以将where
子句放在子查询中。
您不能在查询的where子句中使用分组依据/聚合功能。 一种执行所需操作的方法是使用左联接,如下所示:
select e1.*
from events e1
left join events e2
on e1.director_id = e2.director_id
and e1.event_start > e2.event_start
and date(e1.event_start) = date(e2.event_start)
where e2.director_id is null
如果您在(director_id, event_start)
建立索引,则性能可能会提高
您还可以通过更改and date(e1.event_start) = date(e2.event_start)
来检查特定日期来进一步限制结果大小。
您可以尝试一下:
SELECT
e1.*
FROM events AS e1
INNER JOIN ( SELECT director_id, MIN(event_start) AS `eventStart`
FROM `events` GROUP BY director_id ) AS e2
ON e1.director_id = e2.director_id
AND e1.event_start = e2.eventStart
WHERE e2.eventStart >= '2015-04-27 00:00:00'
AND e2.eventStart < '2015-04-28 00:00:00';
这是sqlfiddle 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.