У меня есть следующие таблицы:
Программы
TYPE_ID | BUILD_ID | CONFIG_ID | VERSION_ID | (All foreign keys to the respective tables)
1 | 1 | 1 | 1 |
1 | 1 | 1 | 2 |
2 | 2 | 3 | 3 |
2 | 2 | 3 | 4 |
Версии
ID | major | minor | patch
1 | 1 |0 |1
2 | 2 |0 |0
3 | 3 |0 |3
4 | 4 |0 |0
Мне нужно выбрать строки с наивысшей версией из таблицы Apps
для каждой уникальной комбинации TYPE_ID
, BUILD_ID
и CONFIG_ID
.
Номер версии должен быть рассчитан MAX(major * 1000000 + minor * 1000 + patch)
в таблице версий.
Таким образом, из приведенного примера таблицы Apps
результат:
TYPE_ID | BUILD_ID | CONFIG_ID | VERSION_ID |
1 | 1 | 1 | 2 |
2 | 2 | 3 | 4 |
Попробовали что-то вроде этого:
SELECT p1.* FROM Apps p1
INNER JOIN (
SELECT max(VERSION_ID) MaxVersion, CONFIG_ID
FROM Apps
GROUP BY CONFIG_ID
) p2
ON p1.CONFIG_ID = p2.CONFIG_ID
AND p1.VERSION_ID = p2.MaxVersion
GROUP BY 'TYPE_ID', 'BUILD_ID', 'CONFIG_ID'
Но MAX
применяется на VERSION_ID
и мне нужно, чтобы MAX
применялся к major
, minor
и patch
комбинациям.
Распространение MySQL версии 15.1 5.5.56-MariaDB
Любая помощь будет оценена по достоинству.
Ура!
Вы можете вычислить максимальную версию для type_id, build_id, config_id
используя формулу, описанную в вашем вопросе, использовать ее снова в той же формуле, чтобы найти версию:
SELECT sq.type_id, sq.build_id, sq.config_id, versions.id AS version_id_max
FROM (
SELECT type_id, build_id, config_id, MAX(major * 1000000 + minor * 1000 + patch) AS max_version
FROM apps
INNER JOIN versions ON apps.version_id = versions.id
GROUP BY type_id, build_id, config_id
) sq
INNER JOIN versions ON max_version = major * 1000000 + minor * 1000 + patch
+---------+----------+-----------+----------------+
| type_id | build_id | config_id | version_id_max |
+---------+----------+-----------+----------------+
| 1 | 1 | 1 | 2 |
| 2 | 2 | 3 | 4 |
+---------+----------+-----------+----------------+
VERSION_ID
в конце вместо последних 5 столбцов? Ура!
*
чтобы показать все детали, включая ненужные).
Попробуй это:
select type_id, build_id, config_id,
max(1000000*v.major+1000*v.minor+v.patch) as version
from apps a left join versions v on a.version_id=v.id
group by type_id, build_id, config_id
Apps
в конечных результатах, поэтому - не принял это как ответ ...
Использование вложенных производных подзапросов и немного хакерского способа идентификации VERSION_ID
соответствующего MAX VERSION_NO
.
Сначала мы получаем сначала производную таблицу, определяющую VERSION_NO
для каждой строки таблицы Apps
.
Теперь, используя эту производную таблицу в качестве источника для SELECT
, мы группируем по TYPE_ID
, BUILD_ID
и CONFIG_ID
и используем трюк GROUP_CONCAT и манипуляции с строкой, мы определяем VERSION_ID
соответствующий максимальному VERSION_NO
, для группы.
Попробуйте следующее:
SELECT nest.TYPE_ID,
nest.BUILD_ID,
nest.CONFIG_ID,
SUBSTRING_INDEX(GROUP_CONCAT(DISTINCT nest.VERSION_ID
ORDER BY nest.VERSION_NO DESC
SEPARATOR ','), ',', 1) AS VERSION_ID
FROM (
SELECT A.TYPE_ID,
A.BUILD_ID,
A.CONFIG_ID,
A.VERSION_ID,
(V.major*1000000 + V.minor*1000 + V.patch) AS VERSION_NO
FROM Apps AS A
INNER JOIN Versions AS V ON V.ID = A.VERSION_ID
) AS nest
GROUP BY nest.TYPE_ID, nest.BUILD_ID, nest.CONFIG_ID
Попробуйте этот запрос, что я здесь делаю, я имитирую известную функцию ROW_NUMBER() OVER (PARTITION BY Type_id, Build_id, Config_id ORDER BY major desc, minor desc, patch desc)
.
select @type_id_lag := 0, @build_id_lag :=0, @config_id_lag := 0, @rn := 0;
select type_id, build_id, config_id, major, minor, patch from (
select case when @type_id_lag = type_id and
@build_id_lag = build_id and
@config_id_lag = config_id then @rn := @rn + 1 else @rn := 1 rn,
@type_id_lag := type_id type_id,
@build_id_lag := build_id build_id,
@config_id_lag := config_id config_id,
v.major, v.minor, v.patch
from Apps a
left join Versions v on a.version_id = v.id
order by a.type_id, a.build_id, a.config_id,
v.major desc, v.minor desc, v.patch desc
) a where rn = 1;
Попробуй это:
SELECT a1.type_id, a1.build_id, a1.config_id, a1.version_id
FROM apps a1
WHERE NOT EXISTS(
(SELECT 'NEXT'
FROM apps a2
WHERE a2.type_id = a1.type_id
AND a2.build_id = a1.build_id
AND a2.config_id = a1.config_id
AND a2.version_id > a1.version_id))