获取 MySQL 中按列分组的最新行

Asg*_*rim 7 mysql select query-refactor

我的问题似乎应该有一个比我想出的更简单的解决方案。从这个数据集开始:

日志表

+--------+-----------+------------------+---------+
| log_id | entity_id |       date       | comment |
+--------+-----------+------------------+---------+
|      1 | A         | 2012-10-23 07:50 | foo     |
|      2 | B         | 2012-10-23 07:59 | bar     |
|      3 | B         | 2012-10-23 08:11 | baz     |
|      4 | A         | 2012-10-23 08:23 | bat     |
+--------+-----------+------------------+---------+
Run Code Online (Sandbox Code Playgroud)

假设我想获取每个实体的日志条目的最新日期,以便结果如下所示:

Results:
+-----------+------------------+--------------+
| entity_id |  last_log_date   | last_comment |
+-----------+------------------+--------------+
| B         | 2012-10-23 08:11 | baz          |
| A         | 2012-10-23 08:23 | bat          |
+-----------+------------------+--------------+
Run Code Online (Sandbox Code Playgroud)

我目前正在使用 MySQL,它看起来像:

SELECT
  `entity_id`,
  `date` AS last_log_date,
  `comment` AS last_comment
FROM (
  SELECT *
  FROM `log_table`
  ORDER BY `date` DESC, log_id ASC
) AS `ordered_log`
GROUP BY `entity_id`
Run Code Online (Sandbox Code Playgroud)

这工作得很好,但它似乎并没有非常有效的对我来说,有是这样做的更好的办法,肯定?

Rol*_*DBA 5

创建一个从log_table每个实体的最大日期收集键的子查询。然后,将该子查询的 INNER JOIN 执行回log_table.

SELECT
    B.entity_id,B.last_log_date,B.last_comment
FROM
(
    SELECT entity_id,MAX(last_log_date) last_log_date
    FROM log_table GROUP BY entity_id
) A INNER JOIN B USING (entity_id,last_log_date);
Run Code Online (Sandbox Code Playgroud)

试一试 !!!

如果你有这样的复合索引,你真的可以加快速度

ALTER TABLE log_table ADD INDEX entity_date_ndx (entity_id,last_log_date);
Run Code Online (Sandbox Code Playgroud)

每个单独列上的索引可能会产生索引合并。这个复合索引将绕过它。

请尝试LEFT JOIN代替INNER JOIN

SELECT
    B.entity_id,B.last_log_date,B.last_comment
FROM
(
    SELECT entity_id,MAX(last_log_date) last_log_date
    FROM log_table GROUP BY entity_id
) A LEFT JOIN B USING (entity_id,last_log_date);
Run Code Online (Sandbox Code Playgroud)