【问题标题】:Find user having continuously three year of attendenance查找连续三年出席的用户
【发布时间】:2023-03-08 02:15:01
【问题描述】:

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

样本数据:

╔════╦══════╦══════╗
║ 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 样品我将不胜感激。

标签: sql sql-server database sql-server-2012 gaps-and-islands


【解决方案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 并将其用作查询的附加组。
猜你喜欢
  • 1970-01-01
  • 2017-06-02
  • 2021-02-02
  • 1970-01-01
  • 2021-03-15
  • 2021-02-20
  • 1970-01-01
  • 2013-11-15
  • 2021-03-06
相关资源
最近更新 更多