哪个是解决子组中最大值的最佳标准 sql 查询

Posted

技术标签:

【中文标题】哪个是解决子组中最大值的最佳标准 sql 查询【英文标题】:Which is the best standard sql query to solve maximum in a subgroup 【发布时间】:2020-11-01 19:43:27 【问题描述】:

我必须进行考试,即使使用 dbms(更准确地说是 mysql)查询也有效。我问自己在形式上是否正确以及在以下问题中哪种形式在形式上更正确,假设表格如下:

create table T(
    k integer primary key not null autoincrement,
    camp1 integer not null,
    camp2 integer not null);

找到 camp2 的每个值的行,其中 camp3 是子集的最大值: 哪个解决方案是正确的,如果它们都正确,那么哪个是形式上最好的?

select * from T group by camp2 having camp3 = max(camp3);

select * from T b group by camp2 having camp3 = (select max(camp3) from T where T.camp2 = b.camp2);

【问题讨论】:

您是否尝试过任何查询?你认为哪一个是正确的? 这个问题在 Stack Overflow 上已经回答过很多次了。我添加了greatest-n-per-group 标签,所以您可以点击它并查看很多答案。 您的表中没有camp3。也是auto_increment 不是autoincrement 【参考方案1】:

最好的方法是关联子查询:

select t.*
from t
where t.camp3 = (select max(t2.camp3) from t t2 where t2.camp2 = t.camp2);

特别是,这可以利用(camp2, camp3) 上的索引。

您的查询应该会产生语法错误,因为它们是格式错误的 SQL 语句——通常不允许使用 select *group by。特别是,聚合查询的 select 中的所有表达式都应该是 group by 键上的表达式,或者它们应该是聚合函数的参数。

尽管上述方法在各种数据库中具有最佳性能(使用正确的索引!),但许多人更喜欢row_number()

select t.*
from (select t.*, row_number() over (partition by camp2 order by camp3 desc) as seqnum
      from t
     ) t
where seqnum = 1;

这也有不错的表现。而在更现代的大规模并行数据库(例如 Redshift、BigQuery、PrestoDB)中,它可能具有更好的性能。

【讨论】:

是标准sql吗? @P.Carlino 。 . . 。是的。您的查询不是。

以上是关于哪个是解决子组中最大值的最佳标准 sql 查询的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:从组中选择最大值和最小值

哪个 SQL 查询更快,为啥?

SQL - 组的子组中的期间范围

使用最大值 SQL 更新组中的所有行

SQL - 组中的 Max() 值不起作用

sql 分组后求每组中的最大值对应的那条数据