P粉6676492532023-08-23 09:25:35
I prefer to use as little code as possible...
You can use IN
to achieve
Try this:
SELECT * FROM t1 WHERE (id,rev) IN ( SELECT id, MAX(rev) FROM t1 GROUP BY id )
In my opinion, this is simpler... easier to read and maintain.
P粉5174756702023-08-23 09:14:22
You only need to use the MAX
aggregate function in the GROUP BY
clause:
SELECT id, MAX(rev) FROM YourTable GROUP BY id
I just noticed that you also need the content
column.
This is a very common problem in SQL: find the complete data corresponding to the maximum value in a column based on a certain grouping identifier. I've heard this question a lot in my career. In fact, I answered one of these questions during a technical interview at my current job.
This question is actually so common that the Stack Overflow community created a tag specifically to deal with this type of problem: greatest-n-per-group.
Basically, you have two ways to solve this problem:
group-identifier, max-value-in-group
Subquery to connectIn this approach, you first find the group-identifier, max-value-in-group
(already solved above) in a subquery. You then join your table with the subquery, using group-identifier
and max-value-in-group
for an equijoin:
SELECT a.id, a.rev, a.contents FROM YourTable a INNER JOIN ( SELECT id, MAX(rev) rev FROM YourTable GROUP BY id ) b ON a.id = b.id AND a.rev = b.rev
In this approach, you left join the table to itself. Equijoin on group-identifier
. Then, there are two clever steps:
NULL
on the right (remember this is a LEFT JOIN
). We then filter the join results to only show rows with NULL
on the right. So, you end up with:
SELECT a.* FROM YourTable a LEFT OUTER JOIN YourTable b ON a.id = b.id AND a.rev < b.rev WHERE b.id IS NULL;
The results obtained by these two methods are exactly the same.
If you have two rows with the same group-identifier
and max-value-in-group
, both methods will include both rows in the result.
Both methods are compatible with SQL ANSI, so no matter which RDBMS you are using, you can use both methods regardless of its "style".
Both methods are very efficient, but the specific effects may be different (RDBMS, database structure, index, etc.). So benchmark when choosing one of these methods. And make sure to choose the method that makes the most sense for you.