CTE的使用
CTE在SQL2005后的版本提供,豐富了查詢的表現形式,下面我們慢慢來看下CTE都能干什么
1、自我遞歸
;WITH myaa AS ( SELECT num=1 UNION ALL SELECT num=num+1 FROM myaa WHERE num<10 ) SELECT * FROM myaa --OPTION (MAXRECURSION 0);--用于限制返回的層級,默認100
2、打印字母表
;WITH myCTE AS
(
SELECT num=65,Mcharacter=CHAR(65)
UNION ALL
SELECT num=num+1,Mcharacter=CHAR(num+1) FROM myCTE WHERE num<90
)
--SELECT ','+Mcharacter FROM myCTE FOR XML PATH('')
SELECT STUFF((SELECT ','+Mcharacter FROM myCTE FOR XML PATH('')),1,1,'')
3、實現Factorial
;WITH myCte AS ( SELECT num=1,faccode=1 UNION ALL SELECT num=num+1,faccode=(num+1)*faccode FROM myCte WHERE num<10 ) SELECT * FROM mycte
看完上面有的朋友要說了,上面的全沒什么用啊,廢材,那下面我們來看一個比較有用的場景,相信很多朋友都不會陌生
4、最最常用的場景
CREATE TABLE #t(id VARCHAR(20),pid VARCHAR(20),NAME VARCHAR(20)) INSERT INTO #t SELECT '001',NULL,'廣東省' UNION ALL SELECT '002','001','廣州市' UNION ALL SELECT '003','001','深圳市' UNION ALL SELECT '004','002','天河區' UNION ALL SELECT '005','003','羅湖區' UNION ALL SELECT '006','003','福田區' UNION ALL SELECT '007','003','寶安區' UNION ALL SELECT '008','007','西鄉鎮' UNION ALL SELECT '009','007','龍華鎮' UNION ALL SELECT '010','007','松崗鎮' ;WITH mycte AS ( SELECT id,pid,NAME,levels=0 FROM #t WHERE id='007' --CTE UNION ALL -- 字段的選取同樣重要 SELECT b.id,b.pid,b.NAME,levels=levels+1 FROM mycte a,#t b WHERE b.pid=a.id --通過CTE的ID與原始表的PID來匹配記錄 ) SELECT * FROM mycte
在這之前我短淺的認為CTE的用法就上面的這么幾種,伴隨著時間的推移我發現了它更廣闊的使用場景,字符串處理、統計,它的身影可以說無處不在,在隨后的備忘中我會貼出CTE在各個方面的使用。
順便提下,在CTE之前,寫遞歸就沒有這么簡單了,下面寫個之前我常用到的方式:
DECLARE @t_level table(id varchar(30),pid VARCHAR(30),NAME VARCHAR(30), level int) DECLARE @id VARCHAR(10),@level INT SET @id='007'; SET @level=1; insert into @t_level select id,pid,name,@level FROM #t WHERE id=@id WHILE @@ROWCOUNT>0 BEGIN SET @level=@level+1 INSERT INTO @t_level SELECT b.id,b.pid,b.name,@level FROM @t_level a INNER JOIN #t b on b.pid=a.id AND a.level=@level-1 END SELECT #t.* FROM #t,@t_level WHERE #t.id=[@t_level].id
總結
- 上一篇: Java为何需要多态机制?
- 下一篇: iOS 13 “查找” App 的使用技