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-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就不是同一個值了。