ORDER BY子查询,用于GROUP BY到JOIN的转换

时间:2011-08-18 21:10:12

标签: mysql sql

我有这张桌子

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

它可以作为魅力,但可以转换为JOIN语句吗?

由于

2 个答案:

答案 0 :(得分:3)

这可以简化为以下内容(子查询中的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标准一致,您甚至可能会发现您的查询完全停止工作并产生错误。

答案 1 :(得分:0)

sql语句无效。

ORDER BY在子查询中无效

GROUP BY需要一个聚合函数,如COUNT,SUM等。

SELECT COUNT(*) FROM table
GROUP BY title
ORDER BY title