这是绝对不是最好的建议。 SQL本身(以及我所知道的MySQL文档)几乎没有关于带有order by
的子查询的结果。虽然他们可能会在实践中下令,但他们不能保证是。
更重要的问题是在聚合中使用“隐藏列”。考虑这个基本查询:除了在select
t.col
select t.*
from (select t.* from table t order by datecol) t
group by t.col;
一切都来自一个不确定行。具体documentation是(重点是我的):
MySQL的扩展使用GROUP BY的,这样的选择列表可参考 在GROUP BY子句中未命名的非聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 以避免不必要的列排序和 分组以获得更好的性能。但是,这对于每个 组中未在GROUP BY中指定的每个 非聚合列中的所有值都相同时都很有用。服务器可以自由选择每组中的任何值,所以 除非它们相同,否则所选值不确定。 此外,每个组的值的选择不能受到添加ORDER BY子句影响的 的影响。结果集 的排序发生在选择了值之后,并且ORDER BY不影响 服务器选择的每个组内的值。
一种安全的方式来写这样的查询是:
select t.*
from table t
where not exists (select 1
from table t2
where t2.col = t.col and t2.datecol < t.datecol
);
这是不完全一样的,因为它会返回多个值,如果最低是不是唯一的。其中的逻辑是“帮我在表中的所有行,其中有具有相同col
值和较小的datecol
值没有行
编辑:
在您的评论的问题是没有意义的,因为没有正在讨论两个查询在MySQL中,你可以使用order by
与变量来解决这个问题:。
select t.*
from (select t.*,
@rn := if(@col = col, @rn := @rn + 1, 1) as rn,
@col := col
from table t cross join
(select @col := '', @rn := 0) vars
order by col, datecol) t
where rn = 1;
这个方法应该比order by
与group by
更快
这里是理论从实践中转移的地方 - 因为实际上,MySQL(迄今为止)的每个(子查询支持)版本将返回排序结果的第一行,而不管文档建议的内容如何。 – Strawberry
这太好了。我明白选择“行”的风险。然而,从性能的角度来看,如果是两个查询,我能够尽可能地优化这个查询吗?也许这是一个单独的问题......我可以接受并询问另一个问题。 –