SQL如何求解連續(xù)性的問題?
點擊上方SQL數(shù)據(jù)庫開發(fā),關(guān)注獲取SQL視頻教程
SQL專欄
SQL數(shù)據(jù)庫基礎(chǔ)知識匯總SQL數(shù)據(jù)庫高級知識匯總有這樣一道題目
下表記錄了奪冠球隊的名稱及年份:

請寫出一條 SQL 語句,查詢出在此期間連續(xù)獲得冠軍的有哪些,其連續(xù)的年份的起止時間是多少?
查詢結(jié)果:

之前我們有講解如何求解連續(xù)多少天的問題,這個題有點類似,但是也有點不一樣的地方。
問題分析
一般連續(xù)性的問題,我們都需要使用笛卡爾積進行錯位匹配,就是類似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解答的結(jié)果如下:

我們對上面的解法進行解讀一下:
首先是給這些數(shù)據(jù)添加一列自增長的RN列并插入到新的臨時表#a并且對TEAM和Y排序。
其次是將#a進行自匹配,匹配的條件是TEAM名稱相同(TEAM=a.TEAM),并且年份Y與前后的年份進行匹配(Y=a.Y-1 OR a.Y=Y-1)。
這個匹配是精妙地方之一,這樣就可以判定該球隊前后幾年的年份是否連續(xù)的。
如果球隊名相同的前提下,年份連續(xù),就滿足這個條件;
如果年份連續(xù),但是球隊名不相同,就不滿足這個條件了。
最后在進行分組的時候,不僅對球隊TEAM進行了分組,而且還對Y-RN進行了分組。為什么要對Y-RN進行分組呢?
如果去掉這個條件,我們發(fā)現(xiàn)如下情形:

公牛和湖人中間間隔了幾年才重新連續(xù)奪冠,但是這里因為沒有對Y-RN進行分組,導(dǎo)致這個球隊和奪冠年份在進行匹配時都滿足了。因為#a表中的內(nèi)容實際上是這樣的,

Y=a.Y-1 OR a.Y=Y-1只要有一個滿足即可判斷是連續(xù)的年份,實際上經(jīng)過我們處理后確實滿足上述條件,所以需要加上Y-RN進行第二次分組來判斷中間是否有間隔的年份。因為如果有間隔,那么Y-RN就不是同一個值了。
——End——
后臺回復(fù)關(guān)鍵字:1024,獲取一份精心整理的技術(shù)干貨后臺回復(fù)關(guān)鍵字:進群,帶你進入高手如云的交流群。推薦閱讀
- SQL 查詢優(yōu)化之 WHERE 和 LIMIT 使用索引的奧秘
- MySQL主從復(fù)制配置詳解
- 神奇的 SQL,GROUP BY 真扎心,原來是這樣!
- 為什么阿里巴巴禁止使用存儲過程?
- 同事給我埋了個坑:INSERT INTO SELECT把生產(chǎn)服務(wù)器炸了
這是一個能學(xué)到技術(shù)的公眾號,歡迎關(guān)注
點擊「閱讀原文」了解SQL訓(xùn)練營