Используя ваши входные данные из вопроса и таблицу без ключей, вот довольно больной подход, который работает:
Прежде всего, вам нужен следующий запрос:
select A.* from prod A LEFT JOIN
(select product_id,max(tagnum) maxtag from
(select *,(version_id*10000+update_id*100+patch_id) tagnum from prod) AA
group by product_id) B
USING (product_id)
WHERE (version_id*10000+update_id*100+patch_id) = B.maxtag;
Вот пример кода с использованием всех целых чисел, без индексов и данных примера:
DROP TABLE IF EXISTS prod;
CREATE TABLE prod
(
product_id INT,
version_id INT,
update_id INT,
patch_id INT
) ENGINE=MyISAM;
INSERT INTO prod VALUES
( 1, 1, 0, 0 ),
( 1, 1, 1, 0 ),
( 1, 1, 1, 1 ),
( 1, 1, 2, 0 ),
( 1, 1, 2, 1 ),
( 2, 1, 0, 0 ),
( 2, 2, 0, 0 ),
( 2, 3, 0, 0 ),
( 2, 3, 0, 1 ),
( 3, 1, 0, 0 ),
( 3, 1, 0, 1 );
select * from prod;
select *,(version_id*10000+update_id*100+patch_id) tagnum from prod;
select A.* from prod A LEFT JOIN
(select product_id,max(tagnum) maxtag from
(select *,(version_id*10000+update_id*100+patch_id) tagnum from prod) AA
group by product_id) B
USING (product_id)
WHERE (version_id*10000+update_id*100+patch_id) = B.maxtag;
Вот результат:
mysql> DROP TABLE IF EXISTS prod;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE prod
-> (
-> product_id INT,
-> version_id INT,
-> update_id INT,
-> patch_id INT
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO prod VALUES
-> ( 1, 1, 0, 0 ),
-> ( 1, 1, 1, 0 ),
-> ( 1, 1, 1, 1 ),
-> ( 1, 1, 2, 0 ),
-> ( 1, 1, 2, 1 ),
-> ( 2, 1, 0, 0 ),
-> ( 2, 2, 0, 0 ),
-> ( 2, 3, 0, 0 ),
-> ( 2, 3, 0, 1 ),
-> ( 3, 1, 0, 0 ),
-> ( 3, 1, 0, 1 );
Query OK, 11 rows affected (0.00 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from prod;
+------------+------------+-----------+----------+
| product_id | version_id | update_id | patch_id |
+------------+------------+-----------+----------+
| 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 |
| 1 | 1 | 2 | 0 |
| 1 | 1 | 2 | 1 |
| 2 | 1 | 0 | 0 |
| 2 | 2 | 0 | 0 |
| 2 | 3 | 0 | 0 |
| 2 | 3 | 0 | 1 |
| 3 | 1 | 0 | 0 |
| 3 | 1 | 0 | 1 |
+------------+------------+-----------+----------+
11 rows in set (0.00 sec)
mysql> select *,(version_id*10000+update_id*100+patch_id) tagnum from prod;
+------------+------------+-----------+----------+--------+
| product_id | version_id | update_id | patch_id | tagnum |
+------------+------------+-----------+----------+--------+
| 1 | 1 | 0 | 0 | 10000 |
| 1 | 1 | 1 | 0 | 10100 |
| 1 | 1 | 1 | 1 | 10101 |
| 1 | 1 | 2 | 0 | 10200 |
| 1 | 1 | 2 | 1 | 10201 |
| 2 | 1 | 0 | 0 | 10000 |
| 2 | 2 | 0 | 0 | 20000 |
| 2 | 3 | 0 | 0 | 30000 |
| 2 | 3 | 0 | 1 | 30001 |
| 3 | 1 | 0 | 0 | 10000 |
| 3 | 1 | 0 | 1 | 10001 |
+------------+------------+-----------+----------+--------+
11 rows in set (0.01 sec)
mysql> select A.* from prod A LEFT JOIN
-> (select product_id,max(tagnum) maxtag from
-> (select *,(version_id*10000+update_id*100+patch_id) tagnum from prod) AA
-> group by product_id) B
-> USING (product_id)
-> WHERE (version_id*10000+update_id*100+patch_id) = B.maxtag;
+------------+------------+-----------+----------+
| product_id | version_id | update_id | patch_id |
+------------+------------+-----------+----------+
| 1 | 1 | 2 | 1 |
| 2 | 3 | 0 | 1 |
| 3 | 1 | 0 | 1 |
+------------+------------+-----------+----------+
3 rows in set (0.00 sec)
mysql>
Попробуйте!
CAVEAT
Мой ответ будет поддерживаться для каждого продукта
- до 99 версий
- до 99 обновлений
- до99 патчей