Sample data:
CREATE TABLE yourtable
(`id` int, `rev` int, content varchar(20))
;
INSERT INTO yourtable
(`id`, `rev`, content)
VALUES
(1, 1, 'a'),
(2, 1, 'b'),
(1, 2, 'c'),
(1, 3, 'd')
;
Solution 1:
SELECT * FROM yourtable AS yt1
LEFT OUTER JOIN yourtable yt2 ON (yt1.id = yt2.id AND FIELD(yt1.rev, 1,3,2) < FIELD(yt2.rev, 1,3,2))
WHERE yt2.id IS NULL;
but I don't like having functions on columns on joins, especially when having a range comparison instead equality comparison.
Solution 2:
SELECT id, rev, content FROM (
SELECT yt.*, @grpnum := IF(id != @prevgrp, 1, @grpnum + 1) as my_filter, @prevgrp := id
FROM yourtable yt,
(SELECT @grpnum:=0, @prevgrp := 0) v
ORDER BY id, FIELD(rev, 1, 3, 2) DESC
) sq
WHERE my_filter = 1;
Result:
| ID | REV | CONTENT |
|----|-----|---------|
| 1 | 2 | c |
| 2 | 1 | b |
Explanation Solution 2:
First I select everything from yourtable
and order it by id
and then by FIELD(rev, 1, 3, 2)
. What does this FIELD()
function do?
Consider this data:
mysql> select id from value order by id;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
Now, when you do
mysql> select id, field(id, 3,2,5) from value order by id;
+----+------------------+
| id | field(id, 3,2,5) |
+----+------------------+
| 1 | 0 |
| 2 | 2 |
| 3 | 1 |
| 4 | 0 |
| 5 | 3 |
| 6 | 0 |
+----+------------------+
You see, that the function returns the index of the column id
in the parameter list of the function. Everything that is not found is returned as 0
.
Read more about it here in the manual.
Since we want to have the maximum, we flip the order in our parameter list of FIELD()
. Instead of FIELD(rev, 2, 3, 1)
we have FIELD(rev, 1, 3, 2)
in assumption, that the priority order is 2 as highest, then 3, then 1. (EDIT: I just saw now, that you have another order and you can of course also use your CASE WHEN
construct, it does the same, the FIELD()
function is just less to write)
Next step is to initialize some variables on the fly in the subquery aliased with v
. It's the same as writing SET @grpnum = 0;
before the query.
When the id changes (note, that it's important we order by id
, then by field()
), we increment another variable. This works as filter in the outer query.
This way we return all of the row corresponding to your defined maximum value in the FIELD()
function.