哪个是解决子组中最大值的最佳标准 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 查询的主要内容,如果未能解决你的问题,请参考以下文章