给定表可以包含以下行。
即对于给定的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
的副本。
注意:为OS和App版本定义单独的列很容易,但是这需要大量代码更改,而我们不希望这样做。
问题:是否有一个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
答案 0 :(得分:1)
问题:是否存在SELECT查询,该查询仅返回file_id = 1和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
)