3

同样的老问题:

我有一张桌子。我想要一个字段的最大值行,按一组字段分组。但我不需要的只是最大值和按字段分组,我需要整行(所有其他字段,所以我不能只做:

select max(field1),  field2 from table group by field2; 

正如我所说,我需要 field3, field4, ... , fieldn。

这已经被处理过,我在这里找到了一个很好的答案:

SQL 仅选择列上具有最大值的行

基本上,它说我应该在原始表之间进行连接,从那里获取所有字段,以及一个子查询,让我得到最大值和按字段分组。在大多数情况下,这可能有效。

我的问题

对于我的特殊情况,由于涉及的数据类型,我不太确定该方法是否有效。让我举个例子。

考虑一下这给了我想要的最大值,按我想要的字段分组:

select max(field1) maxf1, field2 f2 from mytable group by f2

上面的链接建议尝试类似:

SELECT mt.field1, mt.field2, mt.field3, ... , mt.fieldn
FROM mytable mt
INNER JOIN (
    SELECT max(field1) maxf1, field2 f2 FROM mytable GROUP BY f2
) sq
ON sq.maxf1 = mt.field1 AND sq.f2 = mt.field2

对于我的特殊情况,field1 和 field2 可能是 FLOAT 和 TIMESTAMP 类型。因此,连接比较sq.maxf1 = mt.field1可能sq.f2 = mt.field2不是可行的方法(请参阅浮点和双重比较最有效的方法是什么?)。那么,对我有什么提示吗?

4

1 回答 1

3

您的查询很好:

SELECT mt.field1, mt.field2, mt.field3, ... , mt.fieldn
FROM mytable mt
INNER JOIN ( SELECT max(field1) maxf1, field2 f2 
             FROM mytable GROUP BY f2
           ) sq
   ON sq.maxf1 = mt.field1 
     AND sq.f2 = mt.field2

MAX()或者MIN()不会导致浮点舍入问题,如果您正在聚合或执行其他值得关注的计算,但无论如何您都不会使用该字段JOIN

仅供参考:如果您正在做一些其他转换或尝试在一侧和另一侧JOIN使用 a ,一种常见的方法是选择可接受的误差范围并使用绝对值和减法:FLOATDECIMAL

SELECT mt.field1, mt.field2, mt.field3, ... , mt.fieldn
FROM mytable mt
INNER JOIN ( SELECT max(field1) maxf1, field2 f2 
             FROM mytable GROUP BY f2
           ) sq
   ON ABS(sq.maxf1 - mt.field1) < .0001
     AND sq.f2 = mt.field2
于 2013-09-24T19:58:50.880 回答