mysql - GROUP BY 到 JOIN 转换的 ORDER BY 子查询

标签 mysql sql

我有这张 table

id |   title   | amount | timestamp
1  |  random1  |   150  | 1313635011
2  |  random2  |   190  | 1313635730
3  |  random2  |   210  | 1313637359
4  |  random2  |   100  | 1313691807
5  |  random3  |   130  | 1313692673
6  |  random4  |   900  | 1313692739
7  |  random4  |   111  | 1313692988

我想得到这个结果(具有不同标题和最大时间戳的行):

id |   title   | amount | timestamp
1  |  random1  |   150  | 1313635011
4  |  random2  |   100  | 1313691807
5  |  random3  |   130  | 1313692673
7  |  random4  |   111  | 1313692988

我有这个问题。

SELECT * FROM (
  SELECT * FROM table ORDER BY timestamp DESC 
) m GROUP BY title

它可以作为 charm 但它可以转换为 JOIN 语句吗?

谢谢

最佳答案

这可以简化为如下(子查询中的ORDER BY没有用):

SELECT * 
FROM table
GROUP BY title

为什么您认为您需要JOIN? (好的,这已通过评论解决)。


在您对每个标题、具有最大时间戳的行发表评论之后,这将完成工作:

SELECT t.* 
FROM
    table AS t
  JOIN
    ( SELECT title
           , MAX(timestamp) AS maxts
      FROM table
      GROUP BY title
    ) AS grp
    ON grp.title = t.title
    AND grp.maxts = t.timestamp
ORDER BY t.timestamp DESC

作为记录,您的原始查询:

SELECT * 
FROM 
  ( SELECT * 
    FROM table 
    ORDER BY timestamp DESC 
  ) m
GROUP BY title

可能按预期工作,但是:在 MySQL 中允许您在 SELECT 列表字段中使用不在 GROUP BY 子句(或依赖于那些子句),其中没有任何聚合函数。因此,上面的查询将为每个标题返回一个或多或少随机的行。事实上,它将返回为标题找到的第一行。因此,首先运行子查询(按 timestamp DESC 排序)会首先找到具有最大时间戳的行。

然而,这只会发生,因为(当,如果)优化器不明白子查询是无用的。当有一天您升级到 MySQL 版本 7.5 并且您的查询像以前一样停止工作时,您可能会发现您的原始查询运行良好。 (因为优化器变得更聪明并将您的查询转换为更简单的查询而无需子选择)。

如果 MySQL 在未来的版本中决定按照 GROUP BY 查询的 SQL 标准,您甚至可能会发现您的查询完全停止工作并产生错误。

关于mysql - GROUP BY 到 JOIN 转换的 ORDER BY 子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7114173/

相关文章:

python - MySQL - 匹配两个包含巨大数据的表并找到相似的数据

php - 使用 cakephp 查询不更新 Mysql 中的字段

mysql - Django:将两个查询(两个不同模型)中的项目组合在一起

java - 如何在Java中有效地计算CSV文件的行数

sql - 插入数据时使用 Rowlock 有帮助......?

c++ - ODBC - 用 C++ 编写准备好的语句

sql - mySQL返回每个类别的前5名

PHP Mysql 登录

php - 无法将数据存储到 joomla 2.5 中的数据库中

mysql - 在表中制作用户名、正文、msg_date 字段的 id 字段 md5 的最佳方法是什么?