鉴于表可以有以下行。
即,对于一个给定的filename
,可以有两个独特version_id
(一个或多个)。
file_id version_id filename
1 OS_v1 abc.update
1 App_v1 abc.update
2 OS_v2 xyz.update
2 App_v2 xyz.update
3 OS_v1 abc(1).update
3 App_v1 abc(1).update
PRIMARY KEY (`version_id`, `filename`)
如何检测没有两个不同的文件名的有OS_App(版本)的相同的组合?
在给出的示例,一行file_id=3
设置是file_id=1
的副本。
注意:这很容易定义的操作系统和应用程序版本单独的列,但是这需要大量的,我们不希望去通过代码的变化。
问:有没有SELECT
查询这将只返回file_id = 1
和file_id = 2
和省略file_id = 3
?
到目前为止,我想出了这个查询其选择version_id
通过filename
分组的组合,但是行2列-1的复制
SELECT DISTINCT(GROUP_CONCAT(version_id SEPARATOR '-')) ,
filename
FROM schema_name.table_name
GROUP BY filename;
返回:
concat_version patch_filename
OS_V1-APP_V1 xyz.update
OS_V2-APP_V2 abc(1).update
OS_V1-APP_V1 abc.update
问:是否有这将只返回的file_id = 1,SELECT查询的file_id = 2和遗漏的file_id = 3
如果你正在使用MySQL 8.0,你可以利用窗函数ROW_NUMBER()
的:
SELECT x.file_id, x.version_id, x.filename
FROM (
SELECT t.*, ROW_NUMBER() OVER(PARTITION BY version_id ORDER BY file_id) rn
FROM master_logs.system_patches t
) x
WHERE x.rn = 1
内部查询指定一个行号在version_id
组,每组记录,通过file_id
有序,并与行号1
记录外查询过滤器。
与早期版本的MySQL,一个典型的解决方案是使用相关子查询与NOT EXISTS
条件来过滤掉不需要的记录:
SELECT t.file_id, t.version_id, t.filename
FROM master_logs.system_patches t
WHERE NOT EXISTS (
SELECT 1
FROM master_logs.system_patches t1
WHERE t1.version_id = t.version_id AND t1.file_id < t.file_id
)