为包含多列的每个组选择最大版本号

时间:2018-09-14 12:53:04

标签: mysql sql group-by max

我有下表:

应用

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_IDBUILD_IDCONFIG_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应用于majorminorpatch组合。 / p>

MySQL版本15.1发行版5.5.56-MariaDB

任何帮助将不胜感激。

干杯!

3 个答案:

答案 0 :(得分:1)

您可以使用问题中所述的公式来计算每个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 |
+---------+----------+-----------+----------------+

答案 1 :(得分:0)

尝试一下:

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))

答案 2 :(得分:0)

尝试此查询,我在这里做什么,我模仿著名的功能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;