带别名的MySQL SELECT查询在MySQL 5.7.28中不起作用

问题描述 投票:0回答:4

我有以下MySQL表和查询:http://sqlfiddle.com/#!9/13a3c84/2

如您所见,它正在以MySQL 5.6运行。

我要执行以下查询:SELECT * FROM (SELECT * FROM test ORDER BY year DESC) x GROUP BY title;

这将使以下内容:

  1. 按年份DESC排序所有行。
  2. GROUP BY标题将占据第一行。

MySQL 5.6的输出是:

3   Test Name   2017

MySQL 5.7.28相同,给出以下输出:

1   Test Name   2015

我想,MySQL 5.6MySQL 5.7.28之间有所变化,但是呢?

mysql sql mysql-5.7 mysql-5.6
4个回答
0
投票

MySQL 5.7是第一个默认拒绝此类查询的人。您必须为该查询设置sql模式才能运行。

[按某项分组时,select中的所有内容都应在组中或使用聚合函数。

您的查询不明确,因此可以更改。如果要选择最低年份,请使用select title, min(year)

标题很好,因为它属于分组依据。而且年份很好,因为它在聚合函数中


0
投票

您现在获得不同的结果,因为您的查询一开始并不完全正确。

GROUP BY子句允许将来自不同源行的值合并到单个结果集行中。有两种方法可以实现它:

  • 执行产生单个值的计算,例如SUM()COUNT()AVG()
  • 选择给定列始终具有相同值的行,然后选择该值。

您的查询过去一直是不正确的,因为它采用了第三种方法:选择给定列具有不同值的行,并按照没有确定性的规则任意选择其中一个值。

[大多数其他DBMS只会中止查询并引发错误。但是,MySQL传统上一直很宽容,并且很容易产生错误的结果。


0
投票

仅输出标题相同的年份最高的行的正确方法是什么?

您可以使用下面的查询来获得所需的结果。

查询:

select 
    t1.*
from
    test as t1
        left join
    test as t2 ON t1.title = t2.title and t1.year < t2.year
where
    t2.id is null;

输出:

id |标题|年-:| :-------- | ---:3 |测试名称| 2017年4 |测试2016年

小提琴:fiddle here


0
投票

并且在MySQL 8+中(使用默认设置),您会得到一个错误,因为SELECT中的列不在GROUP BY中。顺便说一句,这是正确的行为。您的查询格式不正确。

如果要为每个title选择最新的数据行,那么您应该考虑的是“过滤器”而不是“聚合”。

这意味着您需要where子句(或类似内容)。对于您的问题,我建议使用相关子查询:

select t.*
from test t
where t.year = (select max(t2.year)
                from test t2
                where t2.title = t.title
               );

test(title, year)上有索引,这也应该比您的版本快。

我手头没有这两个版本,以查看您所说的内容是否可复制。如果是这样,则原因可能与子查询结果的实现有关。在MySQL 5.7的不同发行版中,优化程序都得到了改进。

为了使您的版本能够正常工作(我在引号中加上了引号,因为由于SELECT中包含未聚合的列,因此语法无效的SQL),MySQL必须实现子查询。但是,在某些时候,优化器可能认为这是不必要的-基本上忽略了子查询中的ORDER BY。这将解释结果的差异。

无论如何,正确编写查询,这不是问题。

© www.soinside.com 2019 - 2024. All rights reserved.