SQL- With as 用法
SQL With As用法一.WITH AS的含義用AS語言,也叫做子查詢部分(subquery factoring),可以定義一個SQL片斷,該SQL片斷會被整個SQL語句用到。可以使用SQL語句的可讀性更高,也可以在UNION ALL的不同部分,作為提供數據的部分。對于UNION ALL,使用與AS定義了一個UNION ALL語句,當該片斷被調用2次以上,優化器會自動將該WITH AS短語所獲取的數據放入一個Temp表中。而提示meterialize則是強制將WITH AS短語的數據放入一個全局臨時表中。很多查詢通過該方式都可以提高速度。二。使用方法先看下面一個嵌套的查詢語句:SELECT * FROM person.StateProvince其中CountryRegionCode在(從person.CountryRegion選擇CountryRegionCode,其中名稱如 'C%')上面的查詢語句使用了一個子查詢雖然這條SQL語句并不復雜,但如果嵌套的層次過多,會使用SQL語句非常難以閱讀和維護。因此,也可以使用表變量的 來解決這個問題,SQL語句如下:聲明@t表(CountryRegionCode nvarchar的的(3))插入@t(CountryRegionCode)(從person.CountryRegion中選擇CountryRegionCode,其中名稱為 'C%')
select * from person.StateProvince其中CountryRegionCode in(select * from @t)雖然上面的SQL語句要比第一種方式更復雜,但卻將子查詢放在了表變量@t中,這樣做將使SQL語句更容易維護,但又會帶來另一個問題,就是性能的損失。由于表變量實際上使用了臨時表,從而增加了額外的I / O開銷,因此,表變量的方式并不太適合數據量大而頻繁查詢的情況。為此,在SQL Server 2005中提供了另外一種解決方案,這就是公用表表達式(CTE),使用CTE,可以使用SQL語句的可維護性,同時,CTE要比表面量的效率高得多。下面是CTE的語法:[WITH <common _ table _ expression> [,n]] <common _ table _ expression> :: = expression _ name [(column _ name [,n] )] AS(CTE _ query _ definition)現在使用CTE來解決上面的問題,SQL語句如下:
復制代碼用Cr作為(從person.CountryRegion選擇CountryRegionCode,其中名稱就像 'C%')SELECT * FROM person.StateProvince其中CountryRegionCode在(SELECT * FROM CR)復制代碼其中CR是一個公用表表達式,該表達在使用上與表變量類似,只是SQL Server 2005中在處理公用表表式的方式上有所不同。在使用CTE時應注意如下幾點:1.CTE后面必須直接跟使用CTE的SQL語句(如選擇,插入,更新等),否則,CTE將失效如下面的SQL語句將無法正常使用CTE:復制代碼與Cr作為(從person.CountryRegion選擇CountryRegionCode,其中名稱如 'C%')SELECT * FROM person.CountryRegion - - 應用這條SQL語句去掉 - 使用CTE的SQL語句應緊跟在相關的CTE后面 - SELECT * FROM person.StateProvince其中CountryRegionCode在(SELECT * FROM CR)復制代碼2.CTE后面也可以跟其他的CTE,但只能使用一個,多個CTE中間用逗號(,)分隔,如下面的SQL語句所示:復制代碼與cte1 as(select * from table1 where name like'abc%'),cte2 as(
select * from table2,其中id> 20),cte3 as(select * from table3,其中price <100)from cte1 a,cte2 b,cte3 c中選擇a。*,其中a.id = b.id和a。 id = c.ID復制代碼3.如果CTE的表達式名稱與某個數據表或視圖重名,則緊跟在該CTE后面的SQL語句使用的仍然是熱膨脹系數,當然,后面的SQL語句使用的就是數據表或視圖了,如下面的SQL語句所示:復制代碼 - table1是一個實際存在的表,其中table1為(選擇*來自年齡<30的人)select * from table1 - 使用了名為table1的公共表表達式select * from table1 - 使用了名為table1的數據表復制代碼4.CTE可以引用自身,也可以引用在同一與子句中預先定義的CTE。不允許前向引用。復制代碼 - 使用使用DirectReports(ManagerID,EmployeeID,EmployeeLevel)AS ( SELECT ManagerID,EmployeeID,0 AS EmployeeLevel FROM HumanResources.Employee WHERE ManagerID IS NULL )遞歸公用表表達式顯示遞歸的多個級別 UNION ALL SELECT e.ManagerID,e.EmployeeID,EmployeeLevel + 1FROM HumanResources.Employee e INNER JOIN DirectReports d ON e.ManagerID = d.EmployeeID )SELECT ManagerID ,EmployeeID,EmployeeLevel FROM DirectReports; - 使用遞送公用表表達式顯示遞歸的兩個級別WITH DirectReports(ManagerID,EmployeeID,EmployeeLevel)AS ( SELECT ManagerID,EmployeeID,0 AS EmployeeLevel FROM HumanResources.Employee WHERE ManagerID IS NULL UNION ALL SELECT e.ManagerID,e。 EmployeeID,EmployeeLevel + 1 FROM HumanResources.Employee e INNER JOIN DirectReports d ON e.ManagerID = d.EmployeeID )SELECT ManagerID ,EmployeeID,EmployeeLevelFROM DirectReports
WHERE EmployeeLevel <= 2
- 使用遞歸公用表表達式顯示
層次列表與DirectReports(名稱,標題,EmployeeID,EmployeeLevel,排序)
AS(SELECT CONVERT(varchar(255),c.FirstName +''+ c.LastName),
e.Title,
e .EmployeeID,
1,
CONVERT(varchar(255),c.FirstName +''+ c.LastName)
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID IS NULL
UNION ALL
SELECT CONVERT(varchar(255),REPLICATE('|',EmployeeLevel)+
c.FirstName +''+ c.LastName),
e.Title,
e.EmployeeID,
EmployeeLevel + 1,
CONVERT(varchar(255),RTRIM(Sort)+'|'+ FirstName +''+
LastName)
FROM HumanResources.Employee as e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
JOIN DirectReports AS d ON e。 ManagerID = d.EmployeeID
)
SELECT EmployeeID,Name,Title,EmployeeLevel
FROM DirectReports
ORDER BY Sort
- 使用MAXRECURSION取消一條語句
- 可以使用MAXRECURSION來防止不合理的遞歸CTE進入無限循環。以下示例特意創建了一個無限循環,然后使用MAXRECURSION提示將遞歸級別限制為兩級
WITH cte (EmployeeID,ManagerID,Title)如
(
SELECT雇員,經理ID,標題
FROM HumanResources.Employee
WHERE經理ID IS NOT NULL
UNION ALL
SELECT cte.EmployeeID,cte.ManagerID,cte.Title
FROM CTE
JOIN HumanResources.Employee為e
ON cte.ManagerID = e.EmployeeID
)
-Uses MAXRECURSION將遞歸級別限制為2
SELECT EmployeeID,ManagerID,Title
FROM
cte OPTION(MAXRECURSION 2)
- 在更正代碼錯誤之后,就不再需要MAXRECURSION。以下示例顯示了更正后的代碼
WITH cte(EmployeeID,ManagerID,Title)
AS
(
SELECT EmployeeID,ManagerID,Title
FROM HumanResources.Employee
WHERE ManagerID IS NOT NULL
UNION ALL
SELECT e.EmployeeID,e.ManagerID,e.Title
FROM HumanResources.Employee AS e
JOIN cte ON e .ManagerID = cte.EmployeeID
)SELECT EmployeeID,ManagerID,Title FROM cte復制代碼5.不能在CTE _ query _ definition中使用以下子句:(1)COMPUTE或COMPUTE BY(2)ORDER BY(除非指定了TOP子句)(3)INTO (4)帶有查詢提示的OPTION子句(5)for XML(6)for BROWSE 6.如果將CTE用于屬于批處理的一部分的語句中,那么在它之前的語句必須以分號結尾,如下面的SQL所示:復制代碼聲明@s nvarchar(3)設置@s ='C%'; - 必須加分號與t _ tree為(從person.CountryRegion選擇CountryRegionCode其中類似@s名稱)SELECT * FROM person.StateProvince其中CountryRegionCode中(選擇t _ tree *)復制代碼
總結
以上是生活随笔為你收集整理的SQL- With as 用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机原理(3)主板上的CPU,存储器,
- 下一篇: mysql 高可用架构 mha 之五 U