SQL在两个(或更多)列上从表中选择最高值

时间:2012-05-16 13:18:41

标签: sql sql-server

不确定是否有一种优雅的方式来实现这一目标:

数据

ID   Ver   recID  (loads more columns of stuff)  
1     1       1  
2     2       1  
3     3       1  
4     1       2  
5     1       3  
6     2       3  

因此,我们将ID作为主键,将Ver作为版本,并将recID作为记录ID(将所有版本绑定在一起的任意基本ID)。

所以我想从以下数据中获取select,第3,4和6行,即给定记录ID的最高版本。

有一种方法可以使用一个SQL查询执行此操作吗?或者我需要对记录ID执行SELECT DISTINCT,然后单独查询以获得最高值?或者将批次拉入应用程序并从那里过滤?

4 个答案:

答案 0 :(得分:5)

GROUP BY足以获得每个recID的每个最高版本。

SELECT  Ver = MAX(Ver), recID
FROM    YourTable
GROUP BY
        recID

如果您还需要相应的ID,可以将其包装到子选择

SELECT  yt.*
FROM    Yourtable yt
        INNER JOIN (
          SELECT  Ver = MAX(Ver), recID
          FROM    YourTable
          GROUP BY
                  recID
        ) ytm ON ytm.Ver = yt.Ver AND ytm.recID = yt.RecID

或者,根据您使用的SQL Server版本,使用ROW_NUMBER

SELECT  *
FROM    (
          SELECT  ID, Ver, recID
                  , rn = ROW_NUMBER() OVER (PARTITION BY recID ORDER BY Ver DESC)
          FROM    YourTable
        ) yt
WHERE   yt.rn = 1

答案 1 :(得分:5)

为给定的ver获取最大recID很容易。要获取ID,您需要加入一个获得这些最大值的嵌套查询:

select ID, ver, recID from table x
inner join
    (select max(ver) as ver, recID
     from table
     group by recID) y
on x.ver = y.ver and x.recID = y.recID

答案 2 :(得分:2)

您可以使用cte ROW_NUMBER函数:

WITH cte AS(
    SELECT ID, Ver, recID
    ,      ROW_NUMBER()OVER(PARTITION BY recID ORDER BY Ver DESC)as RowNum
    FROM data
)
SELECT ID,Ver,recID FROM cte
WHERE RowNum = 1

答案 3 :(得分:2)

使用子查询的直接示例:

SELECT  a.*
FROM    tab a
WHERE   ver = (
            SELECT max(ver)
            FROM   tab b
            WHERE  b.recId = a.recId
        )

(注意:这假设(recId,ver)的组合是唯一的。通常会对这些列按顺序存在主键或唯一约束,然后该索引可用于优化此查询)

这几乎适用于所有RDBMS-es,尽管相关子查询可能无法有效处理(取决于RDBMS)。尽管如此,它仍然可以在MS SQL 2008中正常工作。