簡體   English   中英

MySQL:獲取給定日期用戶的最低記錄

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM