根据表中每个组的唯一列选择行
Posted
技术标签:
【中文标题】根据表中每个组的唯一列选择行【英文标题】:select the rows based on unique column of each group from the table 【发布时间】:2020-09-10 19:06:08 【问题描述】: ---------------- c_id s_id p_id (customer_id, service_id, provider_id) ---- ---- ------ 1, 1, 1 - 无法选择,因为下一个条目具有相同的 p_id 1, 2, 1 1、3、3 2, 1, 1 2、2、2 2、3、3 3, 1, 3 - 无法选择,因为下一个条目具有相同的 p_id 3, 2, 3 - 无法选择,因为下一个条目具有相同的 p_id 3、3、3编写查询以从上述数据产生以下结果的成本效益高的方法是什么?
---------------- c_id s_id p_id ---- ---- ------ 1, 2, 1 1、3、3 2, 1, 1 2、2、2 2、3、3 3、3、3【问题讨论】:
mysql 5.7.23 @BarbarosÖzhan 无法选择,因为下一个条目具有相同的 p_id 术语“下一个”只有在指定排序顺序后才有意义。同一个 c_id 中的 ORDER BY s_id 是否安全排序? s_id 是否包含从 1 开始的自然数,并且每个单独的 c_id 没有跳过值?是否有可能某些 c_id 具有 p_id 值,例如 1,2,1,1? @Akina 我可以在每一行添加新列timestamp
以根据时间戳对 p_id 进行排序并选择最新的常用 p_id。
向我们展示一些方法,我们会选择最具成本效益的。
【参考方案1】:
在 MySQL 8.0 中,您可以使用 lead()
检索“下一个”p_id
,并使用该信息过滤掉 pid
与下一个值相同的行。
select *
from (
select t.*, lead(p_id) over(partition by c_id order by s_id) lead_p_id
from mytable t
) t
where not p_id <=> lead_p_id
在早期版本中,您通常会使用相关子查询:
select t.*
from mytable t
where not pid <=> (
select p_id
from mytable t1
where t1.c_id = t.c_id and t1.s_id > t.s_id
order by t1.s_id
limit 1
)
【讨论】:
@Akina:谢谢。我为早期版本添加了解决方案。 假设p_id
对于某些 c_id
是 1,2,1,1... 第一行将丢失。
@Akina:我不这么认为(如果我理解正确的话)。两个查询始终使用s_id
对具有相同p_id
的行进行排序。
是的,他是对的@Akina。看看this。恭喜 GMB,这是一个很棒的解决方案。【参考方案2】:
我不太确定这是否是最具成本效益的,但它似乎是我能想到的最明显的解决方案。
select
c_id
,max(s_id) [s_id]
,p_id
from
`table_name`
group by
c_id
,p_id
【讨论】:
【参考方案3】:如果s_id
是一个没有间隙的序列,你可以使用:
select t.*
from t left join
t tnext
on tnext.c_id = t.c_id and tnext.s_id = t.sid + 1
where not (tnext.p_id <=> t.p_id);
【讨论】:
以上是关于根据表中每个组的唯一列选择行的主要内容,如果未能解决你的问题,请参考以下文章