选择top 1,最多2个字段

时间:2014-01-29 20:00:04

标签: sql sql-server

我有这张桌子:

+------+-------+------------------------------------+
| id   | rev   | class                              |
+------+-------+------------------------------------+
| 1    | 10    | 2                                  |
| 1    | 10    | 5                                  |

| 2    | 40    | 6                                  |
| 2    | 50    | 6                                  |
| 2    | 52    | 1                                  |

| 3    | 33    | 3                                  |
| 3    | 63    | 5                                  |
+------+-------+------------------------------------+

我只需要rev AND然后class列具有最大值的行。

+------+-------+------------------------------------+
| id   | rev   | class                              |
+------+-------+------------------------------------+
| 1    | 10    | 5                                  |
| 2    | 52    | 1                                  |
| 3    | 63    | 5                                  |
+------+-------+------------------------------------+

查询费用对我来说很重要。

4 个答案:

答案 0 :(得分:1)

只是满足条件的行才有两个最大值?

这是SQL Fiddle;

SELECT  h.id, h.rev, h.class
FROM (  SELECT  id, 
                MAX( rev ) rev, 
                MAX( class ) class
        FROM    Herp
        GROUP BY id ) derp
INNER JOIN Herp h
    ON  h.rev = derp.rev
    AND h.class = derp.class;

答案 1 :(得分:1)

最快的方法可能是在t(id, rev)t(id, class)上建立一个索引然后执行:

select t.*
from table t
where not exists (select 1
                  from table t2
                  where t2.id = t.id and t2.rev > t.rev
                 ) and
      not exists (select 1
                  from table t2
                  where t2.id = t.id and t2.class > t.class
                 );

SQL Server在优化方面非常聪明,因此聚合方法可能同样出色。但是,就性能而言,这只是一堆索引查找。

答案 2 :(得分:1)

这是一个SQL 2012示例。使用隐含表和PARTITION功能非常简单。

基本上,将每个ID作为分区/组,按降序对其他字段的值进行排序,为每个字段分配一个递增的RowId,然后只取第一个。

select id, rev, [class]
from
    (
        SELECT id, rev, [class], 
        ROW_NUMBER() OVER(PARTITION BY id ORDER BY rev DESC, [class] desc) AS RowId
        FROM sample
    ) t
where RowId = 1

以下是SQL Fiddle

请记住,这适用于示例数据集中的条件,而不是问题标题中所述的两个字段的MAX。

答案 3 :(得分:0)

我想你的意思是:rev的最大值和class的最大值。如果没有,请说明当没有两个字段具有最高值的行时该怎么做。

select id
,      max(rev)
,      max(class)
from   table
group
by     id

如果您的意思是revclass的总价值使用此值:

select id
,      max
,      rev
from   table
where  id in
       (  select id
          ,      max(rev + class)
          from   table
          group
          by     id
       )