查找连续三年出席的用户

Posted

技术标签:

【中文标题】查找连续三年出席的用户【英文标题】:Find user having continuously three year of attendenance 【发布时间】:2015-10-17 13:41:41 【问题描述】:

我有一个事件表,其中将存储参与的用户列表。

样本数据:

╔════╦══════╦══════╗
║ id ║ name ║ year ║
╠════╬══════╬══════╣
║  1 ║ Arun ║ 2001 ║
║  2 ║ Arun ║ 2002 ║
║  3 ║ Arun ║ 2003 ║
║  4 ║ Arun ║ 2004 ║
║  5 ║ Arun ║ 2009 ║
║  6 ║ Arun ║ 2010 ║
║  7 ║ Arun ║ 2011 ║
║  8 ║ Bala ║ 2014 ║
║  9 ║ Bala ║ 2015 ║
║ 10 ║ Bala ║ 2017 ║
║ 11 ║ chan ║ 2014 ║
║ 12 ║ chan ║ 2015 ║
║ 13 ║ chan ║ 2018 ║
╚════╩══════╩══════╝

我只需要在新列中找到连续参加三年的用户。即使用户连续参加了 6 年,也必须在一个列中拆分为前三个,在另一列中拆分为后三个。

输出:

╔════╦══════╦═══════════╗
║ id ║ name ║   years   ║
╠════╬══════╬═══════════╣
║  1 ║ Arun ║ 2001-2003 ║
║  2 ║ Arun ║ 2009-2011 ║
╚════╩══════╩═══════════╝

【问题讨论】:

搜索间隙和岛屿 @Frisbee 样品我将不胜感激。 【参考方案1】:

使用yearrow_number() 生成的递增序列之间的差异获取此信息的一种方法:

select name, min(year), max(year)
from (select e.*,
             (year - row_number() over (partition by name order by year)
             ) as grp
      from events e
     ) e
group by name, grp
having count(*) >= 3;

这将找到任意长度的序列。如果你真的只关心3年,那么你也可以使用joins:

select e.name, e.year as FirstYearOfAtLeastThree
from events e
where exists (select 1 from events e2 where e2.name = e.name and e2.year = e.year + 1) and
      exists (select 1 from events e2 where e2.name = e.name and e2.year = e.year + 2) ;

这两者都可以利用events(name, year) 上的索引。第二种方法可能比第一种方法快一点。

【讨论】:

我已经更新了我的问题,你能相应地修改吗? @Ragul 。 . .任何一个答案仍然是合适的。也许您想要= 3 作为第一个条件。唯一的区别是年份位于两个不同的列中,但是将它们连接在一起(如果您需要的话)并不是特别难。 这正是我所需要的,这就是我听到的原因,我需要每 3 年连接一次并使用联合子句加入它们。样品将我非常感激。 您可以添加另一个 row_number() over( partition by grp order by year) 并将其除以 3 并将其用作查询的附加组。

以上是关于查找连续三年出席的用户的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL:查找到现在为止的连续天数

查找连续序列并建议序列中的下一个数字

查找具有已定义结束的连续相同值的行组 (SQL Redshift)

性能倒退三年?iOS 14.5.1“降速门”一个按钮就解决

当用户连续执行多个graphql突变时防止竞争条件

连续区间的二分查找