我有一个包含serval表的数据库,这些表包含有关我们在各种环境中部署的软件包的信息。然后询问该数据库,以全面了解所安装软件的最新版本,该软件显示在网页的表格中。
我正在尝试做什么,并且正在努力获得每个环境中安装的每个软件包的最新版本。我开始使用这篇文章中的信息:
Retrieving the last record in each group
这对软件的另一个方面有很大帮助,但我倒下的地方是因为我有多个标准可供选择。数据库的相关部分如下
包版本表
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生成的,因此它的格式为x.x.x,并且可以包含SNAPSHOT。
其他尝试只是为我提供了安装在任何地方的最新版本。
我想我需要在LEFT加入部分添加一些东西,但我真的很难弄清楚什么。感谢任何帮助。
非常感谢,
拉塞尔
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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的建议。
罗素