1

我有一个数据库,其中包含多个表,这些表包含有关我们已部署到各种环境中的包的信息。然后查询该数据库以给出已安装软件的最新版本的总体图片,该图片显示在网页上的表格中。

我正在尝试做并且正在努力的是获取每个环境中安装的每个软件包的最新版本。我开始使用这篇文章中的信息:

检索每个组中的最后一条记录

这对软件的另一个方面有很大帮助,但我失败的地方是因为我有多个选择标准。数据库相关部分如下

包版本表

package_versions

id
server_name_id
package_name_id
version

包名表

package_names

id
name

服务器名称表

server_names

id
name
environment_name_id

最后是环境名称表

environment_names

id
name

这种结构允许我保存部署到各种环境中的包和版本的历史记录。

现在我需要做的是获取每个环境中部署的所有包的最新版本。正如我所说,当我使用一张桌子和两个标准时,我已经成功地使用了上面帖子中的解决方案,但这里是 4 张桌子和 2 个标准。

我的尝试要么将已安装在环境中的每个版本都还给我:

SELECT  environment_names.name as environment,
        package_names.display as package,
        package_names.name as pkg_name,
        package_versions.version as package_version
FROM    package_versions INNER JOIN package_names ON package_names.id = package_versions.package_name_id
                         INNER JOIN server_names ON server_names.id = package_versions.server_name_id
                         INNER JOIN environment_names ON environment_names.id = server_names.environment_name_id
                         LEFT JOIN package_versions pv ON (package_versions.package_name_id = pv.package_name_id 
                                                           AND package_versions.id < pv.id)
AND     pv.id IS NULL
ORDER BY environment_names.name, package_names.name

不能只在版本号上使用 Max,因为它是由 Maven 生成的,因此它的格式为 xxx 并且可以包含 SNAPSHOT。

其他尝试只是为我提供了安装在任何地方的最新版本。

我想我需要在左连接部分添加一些东西,但我真的很难弄清楚什么。任何帮助都将不胜感激。

非常感谢,

罗素

4

3 回答 3

1

您需要的是 MySQL 目前不提供的排名功能。有一种方法可以模拟它。此外,您需要拆分版本值以便对它们进行排序。

Select envName, pkgName, version
From (
      Select envName, pkgName, version
        , @rnk := if(@env=envId && @pkg=package_name_id, if(@pkgVer=verId, @rnk, @rnk + 1), 1) As rnk
        , @pkgVer := verId
        , @env := envId
        , @pkg := package_name_id
      From (
            Select env.id As envId
              , env.name As envName
              , ver.package_name_id
              , pkg.name As pkgName
              , ver.id As verId
              , ver.version
              , Cast(Substring_Index( ver.version , '.', 1 ) As signed) As Major
              , Cast(Substring_Index(Substring_Index( ver.version , '.', 2 ),'.',-1) As signed) As Minor
              , Cast(Substring_Index(Substring_Index( ver.version , '.', -2 ),'.',1) As signed) As Build
              , Cast(Substring_Index( ver.version , '.', -1 ) As signed) As Revision
            From package_versions As ver
              Join package_names As pkg
                On pkg.id = ver.package_name_id
              Join server_names As sys
                  On sys.id = ver.server_name_id
              Join environment_names As env
                  On env.id = sys.environment_name_id
              Cross Join ( Select @rnk := 0
                              , @ver := ''
                              , @env := 0
                              , @pkg := 0 ) As Z
          ) As envPackages
      Order By envName, pkgName, Major Desc, Minor Desc, Build Desc, Revision Desc
      ) As rnkedPackages
Where rnk = 1
Order By envName, pkgName, rnk

SQL小提琴

于 2013-05-03T18:38:14.620 回答
0
SELECT environment_names.name as environment,
       package_names.display as package,
       package_names.name as pkg_name,
       MAX(package_versions.version) as package_version
FROM package_versions 
INNER JOIN package_names ON package_names.id = package_versions.package_name_id                             
INNER JOIN server_names ON server_names.id = package_versions.server_name_id                             
INNER JOIN environment_names ON environment_names.id = server_names.environment_name_id
GROUP BY environment_names.name,
         package_names.display,
         package_names.name
ORDER BY environment_names.name, package_names.name
于 2013-05-03T14:09:27.810 回答
0

全部,

非常感谢所有的建议,他们都有帮助。

我放在 package_versions.id 或 package_versions.deploy_time 周围的 MAX() 函数都没有正常工作。例如,我似乎获得了最新的版本 ID,但实际版本号与该记录不匹配。

我发现这是因为我需要使用两个表来获取环境名称。我现在已经向 PackageVersions 表添加了一个关系,这样我就不必使用服务器表作为中介。所以现在表格看起来像:

包版本表

package_versions

id
package_name_id
environment_name_id
version

(server_name_id 仍然在那里,以便我可以使用它为我提供有关环境的更多详细信息)。

包名称表

package_names

id
name

环境名称表

environment_names

id
name

现在我的 SQL 查询看起来像:

SELECT  package_versions.id,
        environment_names.name,
        package_names.name,
        package_versions.version,
        max(package_versions.id)
FROM    package_versions INNER JOIN environment_names ON package_versions.environment_name_id = environment_names.id
                         INNER JOIN package_names ON package_names.id = package_versions.package_name_id
GROUP BY environment_names.id, package_names.name                        
ORDER BY environment_names.name, package_names.name;

这现在为我提供了我需要的信息,并与我正在用这个新代码替换的系统相匹配。

感谢 Lucas 和 Nagaski 的建议。

罗素

于 2013-05-07T10:31:48.850 回答