如何在 MySQL 查询中过滤少量重复项
How can i filter few repeatation in MySQL Query
我有一个 mysql table 如下所示。它用于存储带有版本控制的文档。
我想要 select 最新的 docid(具有最高的主要版本和次要版本)。它将消除所有相同的文档 ID,只获取具有最高 major_version 和 minor_version 的文档。所以我想要如下结果。
一种方法使用 row_number()
:
select t.*
from (select t.*,
row_number() over (partition by docid order by major_version desc, minor_version desc) as seqnum
from t
) t
where seqnum = 1;
这在早期版本中是一个痛苦。可能最简单和最有效的方法是使用变量:
select t.*
from (select t.*,
(@rn := if(@d = docid, @rn + 1,
if(@d := docid, 1, 1)
)
) as rn
from (select t.*
from t
order by docid, major_version desc, minor_version desc
) t cross join
(select @rn := 0, @d := '') params
) t
where rn = 1;
在 MySQL 8.0 中,您可以使用 row_number()
:
进行过滤
select *
from (
select
t.*,
row_number() over(partition by id, docid order by major_version, minor_version) rn
from mytable t
) t
where rn = 1
在早期版本中,您可以使用相关子查询进行过滤。假设您在 table 列中有一个主键,例如 pk
列,您可以执行以下操作:
select t.*
from mytable t
where t.pk = (
select t1.pk
from mytable t1
where t1.id = t.id and t1.docid = t.docid
order by t1.major_version desc, t1.minor_version desc
limit 1
)
为了提高性能,请考虑 (id, docid, major_version, minor_version)
上的索引。
没有可以作为主键的唯一列,稍微复杂一点。一种方法是使用 not exists
:
select t.*
from mytable t
where not exists (
select 1
from mytable t1
where
t1.id = t.id
and t1.docid = t.docid
and (
t1.major_version > t.major_version
or (t1.major_version = t.major_version and t1.minor_version > t.minor_version)
)
)
我有一个 mysql table 如下所示。它用于存储带有版本控制的文档。
我想要 select 最新的 docid(具有最高的主要版本和次要版本)。它将消除所有相同的文档 ID,只获取具有最高 major_version 和 minor_version 的文档。所以我想要如下结果。
一种方法使用 row_number()
:
select t.*
from (select t.*,
row_number() over (partition by docid order by major_version desc, minor_version desc) as seqnum
from t
) t
where seqnum = 1;
这在早期版本中是一个痛苦。可能最简单和最有效的方法是使用变量:
select t.*
from (select t.*,
(@rn := if(@d = docid, @rn + 1,
if(@d := docid, 1, 1)
)
) as rn
from (select t.*
from t
order by docid, major_version desc, minor_version desc
) t cross join
(select @rn := 0, @d := '') params
) t
where rn = 1;
在 MySQL 8.0 中,您可以使用 row_number()
:
select *
from (
select
t.*,
row_number() over(partition by id, docid order by major_version, minor_version) rn
from mytable t
) t
where rn = 1
在早期版本中,您可以使用相关子查询进行过滤。假设您在 table 列中有一个主键,例如 pk
列,您可以执行以下操作:
select t.*
from mytable t
where t.pk = (
select t1.pk
from mytable t1
where t1.id = t.id and t1.docid = t.docid
order by t1.major_version desc, t1.minor_version desc
limit 1
)
为了提高性能,请考虑 (id, docid, major_version, minor_version)
上的索引。
没有可以作为主键的唯一列,稍微复杂一点。一种方法是使用 not exists
:
select t.*
from mytable t
where not exists (
select 1
from mytable t1
where
t1.id = t.id
and t1.docid = t.docid
and (
t1.major_version > t.major_version
or (t1.major_version = t.major_version and t1.minor_version > t.minor_version)
)
)