MySQL:获取给定日期用户的最低记录

时间:2015-04-27 05:27:39

标签: mysql

我有一个事件表,每个人都有一个负责人。每天可能有多个这样的事件,但我需要在给定的一天为每个用户提供 first 的查询记录。

例如,如果我有以下事件表:

+----------+-------------+---------------------+
| 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不支持MIN子句simple SQL query giving Invalid use of group function中的WHERE

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条记录。

3 个答案:

答案 0 :(得分:2)

您可以使用类似于您的查询获得每天的最短活动时间:

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子句放在子查询中。

答案 1 :(得分:0)

您无法在查询的where子句中使用group by / aggregate函数。做你想做的事的一种方法是使用左连接:

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

fiddle here

如果您的索引跨(director_id, event_start)

,则效果可能会提高

您还可以通过更改and date(e1.event_start) = date(e2.event_start)来检查特定日期来进一步限制结果大小。

答案 2 :(得分:0)

你可以尝试一下:

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