4

not sure if there's an elegant way to acheive this:

Data

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  

So, we have ID as the Primary Key, the Ver as the version and recID as a record ID (an arbitary base ID to tie all the versions together).

So I'd like to select from the following data, rows 3, 4 and 6. i.e. the highest version for a given record ID.

Is there a way to do this with one SQL query? Or would I need to do a SELECT DISTINCT on the record ID, then a seperate query to get the highest value? Or pull the lot into the application and filter from there?

4
  • 1
    What database are you using? The most general approach is to use row_number(), but this is not available on all DBS. Commented May 16, 2012 at 13:23
  • It's MS SQL server 2008, however I'd prefer something more agnostic ideally
    – RemarkLima
    Commented May 16, 2012 at 13:24
  • As a caution, all the solutions that use a group by assume that there is only one vers per rec.. Is this the case? Of duplicates, do you want multiple rows or just one? Commented May 16, 2012 at 13:35
  • There's should never be any duplicated "ver" per record ID, as this is incrimented in the application layer... Well that's the plan!
    – RemarkLima
    Commented May 16, 2012 at 16:26

4 Answers 4

5

A GROUP BY would be sufficient to get each maximum version for every recID.

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

If you also need the corresponding ID, you can wrap this into a subselect

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

or, depending on the SQL Server version you are using, use 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
5
  • This assumes that there is only one max per recid. Commented May 16, 2012 at 13:33
  • thank you, very speedy response and you just pipped Jason to the post for the answer!
    – RemarkLima
    Commented May 16, 2012 at 13:38
  • @GordonLinoff - From the question (selecting "the highest version" for each recId) it seems that there is only one max.
    – dj18
    Commented May 16, 2012 at 13:41
  • @GordonLinoff - True for the none ROW_NUMBER version. Perhaps another reason to prefer ROW_NUMBER. Commented May 16, 2012 at 13:43
  • @dj18 Correct, I'm just after the highest "Ver" per distinct recID!
    – RemarkLima
    Commented May 16, 2012 at 16:25
5

Getting maximum ver for a given recID is easy. To get the ID, you need to join on a nested query that gets these maximums:

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
1
  • this is the best answer as it's matching rest of the results in column to the highest value, thanks for that
    – David
    Commented Aug 13, 2018 at 12:31
2

You could use a cte with ROW_NUMBER function:

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
2

straighforward example using a subquery:

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

(Note: this assumes that the combination of (recId, ver) is unique. Typically there would be a primary key or unique constraint on those columns, in that order, and then that index can be used to optimize this query)

This works on almost all RDBMS-es, although the correlated subquery might not be handled very efficiently (depending on RDBMS). SHould work fine in MS SQL 2008 though.

1
  • Thank you, this is a great alternateive and I'll check which one is quicker for my needs and setup - a good alternative to the GROUP BY
    – RemarkLima
    Commented May 16, 2012 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.