点击上方SQL数据库开发,关注获取SQL视频教程
SQL专栏
有这样一道题目
下表记录了夺冠球队的名称及年份:

请写出一条 SQL 语句,查询出在此期间连续获得冠军的有哪些,其连续的年份的起止时间是多少?
查询结果:

之前我们有讲解如何求解连续多少天的问题,这个题有点类似,但是也有点不一样的地方。
问题分析
一般连续性的问题,我们都需要使用笛卡尔积进行错位匹配,就是类似a.ID=b.ID+1的这种。这一题我们也可以使用类似的方法。
具体代码如下:
CREATE TABLE #t(TEAM varchar(20), Y int)INSERT #t(TEAM,Y) VALUES('活塞',1990),('公牛',1991),('公牛',1992),('公牛',1993),('火箭',1994),('火箭',1995),('公牛',1996),('公牛',1997),('公牛',1998),('马刺',1999),('湖人',2000),('湖人',2001),('湖人',2002),('马刺',2003),('活塞',2004),('马刺',2005),('热火',2006),('马刺',2007),('凯尔特人',2008),('湖人',2009),('湖人',2010);SELECT RN=IDENTITY(INT),* INTO #a FROM #t ORDER BY TEAM,Y SELECT a.TEAM, MIN(a.Y) B, MAX(a.Y) E FROM #a a WHERE EXISTS( SELECT 1 FROM #a WHERE TEAM=a.TEAM AND (Y=a.Y-1 OR a.Y=Y-1) ) GROUP BY a.TEAM,Y-RNDROP TABLE #t,#a解答的结果如下:

我们对上面的解法进行解读一下:
首先是给这些数据添加一列自增长的RN列并插入到新的临时表#a并且对TEAM和Y排序。
其次是将#a进行自匹配,匹配的条件是TEAM名称相同(TEAM=a.TEAM),并且年份Y与前后的年份进行匹配(Y=a.Y-1 OR a.Y=Y-1)。
这个匹配是精妙地方之一,这样就可以判定该球队前后几年的年份是否连续的。
如果球队名相同的前提下,年份连续,就满足这个条件;
如果年份连续,但是球队名不相同,就不满足这个条件了。
最后在进行分组的时候,不仅对球队TEAM进行了分组,而且还对Y-RN进行了分组。为什么要对Y-RN进行分组呢?
如果去掉这个条件,我们发现如下情形:

公牛和湖人中间间隔了几年才重新连续夺冠,但是这里因为没有对Y-RN进行分组,导致这个球队和夺冠年份在进行匹配时都满足了。因为#a表中的内容实际上是这样的,

Y=a.Y-1 OR a.Y=Y-1只要有一个满足即可判断是连续的年份,实际上经过我们处理后确实满足上述条件,所以需要加上Y-RN进行第二次分组来判断中间是否有间隔的年份。因为如果有间隔,那么Y-RN就不是同一个值了。
——End—— 后台回复关键字:1024,获取一份精心整理的技术干货 后台回复关键字:进群,带你进入高手如云的交流群。 推荐阅读
SQL 查询优化之 WHERE 和 LIMIT 使用索引的奥秘 MySQL主从复制配置详解 神奇的 SQL,GROUP BY 真扎心,原来是这样! 为什么阿里巴巴禁止使用存储过程? 同事给我埋了个坑:INSERT INTO SELECT把生产服务器炸了
这是一个能学到技术的公众号,欢迎关注
点击「阅读原文」了解SQL训练营最后修改时间:2020-05-12 08:14:37
文章转载自SQL数据库开发,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




