SQL如何求解连续年份的问题?
2023-03-14 09:39:28 时间
本文转载自微信公众号「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-RN
- DROP 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就不是同一个值了。
相关文章
- 谷歌发布新编程语言,专治SQL各种“不服”
- JavaEE中遗漏的10个最重要的安全控制
- 如何在O(1)内找到实时序列的最小值?
- Seata 分布式事务 XA 与 AT 全面解析
- 绝了!这个MySQL故障定位方法太好用了
- Redis 高可用篇:Cluster 集群能支撑的数据有多大?
- Websocket库Ws原理分析
- 《吃透 MQ 系列》之打通 Kafka 的任督二脉
- 谷歌这个牛逼的开源数据库,我居然等到它上Github热榜才发现
- 热点推荐:2016年热门技术方向预测
- 一文搞定消息队列(MQ)之生产者-消费者
- 穷人的量子比特:量子计算机太难造了,先试试概率计算机?
- 字节前端都知道的CSS包含块规则
- 第一个世界量子日,量子计算大牛Scott Aaronson获颁ACM计算奖
- 全栈CMS系统服务端启动细节复盘
- Netfileter & Iptables 实现之 Netfilter实现
- 双写兜兜转转,又回到了串行化的方式
- 不停止 MySQL 服务增加从库的两种方式
- 本科作业到Nature子刊:大二学生突破量子计算近20年的纠错码难题
- 压缩版styleGAN,合成高保真图像,参数更少、计算复杂度更低