tags:

views:

47

answers:

2

I have a table with the following basic structure.

unique_id | name | original | version
-----------------
1 | a1 | 1 | 1

2 | b1 | 2 | 1

3 | a2 | 1 | 2

4 | a3 | 1 | 3

5 | c1 | 5 | 1

6 | b2 | 2 | 2

Now it should be obvious from this that there is a form of version control, where we keep track of the original document, and also track the version of the current document.

If I want to get the latest version of a particular document I do something like the following.

SELECT * FROM table WHERE original = (SELECT original FROM table WHERE id = 3) ORDER BY version DESC

My question is, how do I do get a list of all of the most recent versions in the table with only one query?

A: 

I think you'll find your answer in this question.

T.J. Crowder
If I understand it, the query you have provided as an answer gets the highest version (3 in this case) are returns all records with this version. That is not what I want.I want it to return the latest version of each article, whether that be version 1, version 4 or version 2, just so long as it is the latest.
Philip Bennison
@Philip: No, the linked question does exactly that, finds the latest version of each article (so article A can be version 2, article B version 14). Some of the answers are wrong (the same interpretation you just gave), but the one I posted in that question is correct.
T.J. Crowder
Specifically, this answer: http://stackoverflow.com/questions/1305473/mysql-query-question/1305642#1305642
T.J. Crowder
+2  A: 

The idea is to

  • build a list of all original ID's with the current maximum version
  • join your table with this list of unique identifiers.
SELECT *
FROM table t
     INNER JOIN (     
       SELECT original, MAX(version) as version
       FROM tabel
       GROUP BY original
     ) tmax ON tmax.original = t.original and tmax.version = t.version
Lieven
Great. That seems to work perfectly. Thanks!
Philip Bennison
That will work, but it involves a corrolated subquery, which has performance implications. See http://stackoverflow.com/questions/1305473/mysql-query-question/1305642#1305642 for a more optimal approach.
T.J. Crowder
This is not a corrolated subquery.
Lieven
as a side not, the OP should measure each solution's performance and draw his conclusions from that. I doubt you'll find a more optimal solution than the INNER JOIN scenario.
Lieven
Sorry, you're right; misread it. It does create a temp table, though, which the other solution avoids. Curiously, MySQL 5.1.30 doesn't like the syntax; think it must be a bug. Ran into this in the other q, too. "Unknown column 'tmax.version' in 'on clause'" You can work around it, though, using `AS`: `SELECT t.original, t.version FROM yourTableName t INNER JOIN (SELECT original, MAX(version) AS vmax FROM yourTableName GROUP BY original) tmax ON tmax.original = t.original and tmax.vmax = t.version;`
T.J. Crowder
Thank you. I've adjusted the answer to take care of the syntax issue. Now all we need to resolve is the performance issue <g>.
Lieven
Create a composite index on `(original, version)` to get rid on temptable.
Quassnoi
@Quassnoi: what took you so long? ;)
Lieven
Might have missed this question when it was just asked :)
Quassnoi