SQLServer連接查詢之Cross Apply和Outer Apply的區別及用法
https://blog.csdn.net/wikey_zhang/article/details/77480118
先簡單了解下cross apply的語法以及會產生什麽樣的結果集吧!
示例表:
SELECT * FROM tableA CROSS APPLY tableB
兩張表直接連接,不需要任何的關聯條件,產生的結果就是這兩張表的笛卡兒集,在這裏和上一篇帖子講的cross join交叉連接的結果集是一樣的
相當於:select * from tableA,tableB
與之對應的還有Out Apply,下面講解一下Cross Apply 和 Outer Apply 的區別:
首先是Cross Apply:
SELECT * FROM tableA a CROSS APPLY (select * from tableB where id=a.id) b
這個結果集和 select * from tableA a inner join tableB b on a.id=b.id 一模一樣,這就相當於inner join 的連接查詢嘛!當然,你也可以這樣寫:
- SELECT * FROM tableA a CROSS APPLY tableB b
- WHERE a.id=b.id
結果集一模一樣無差別!
其次是Outer Apply:
SELECT * FROM tableA a OUTER APPLY (select * from tableB where id=a.id) b
發現了吧!這個結果集和left join連接查詢產生的結果集一模一樣~
同時,發現Cross Apply 和 Cross JOin 的區別了沒?
Cross Apply 可以在關聯表子查詢中用前一個關聯表的字段的值,而Cross Join 卻不行,比如這樣寫:SELECT * FROM tableA a CROSS JOIN (select * from tableB where id=a.id) b,語法上就不能通過!
針對這一點,下面列舉一些Cross Apply特有的用法:
1.結合表值函數使用:
有一張表是這樣的:
很簡單的一張表,就一個字段num,我想把這個字段的int型數字分別轉化成二進制八進制和十六進制的數值,有現成的進制轉化的表值函數,我前面關於函數的講解有寫過這個函數的例子:點擊打開鏈接
SELECT * FROM #T a CROSS APPLY [dbo].[F_TConversion](a.num)
實現這個結果集用CROSS APPLY,只要一句就能實現,如果換成其他的方法的話應該沒這麽簡單哈~
總結一下:
如果查詢結果集需要用到表值函數對某個字段的值進行處理的話,請使用CROSS APPLY~
2.top子查詢的用法:
有一張學生表,分別name,學科,分數 這三個字段,如下:
我要看語文第一名,數學前兩名,英語前三名的name,學科,分數,用cross apply實現方法如下:
- SELECT b.* FROM (
- select Subject=‘Chiness‘,num=1 union all
- select ‘Math‘,2 union all
- select ‘English‘,3
- )a cross apply (select top(a.num) * from Students where Subject=a.Subject )b
SQLServer連接查詢之Cross Apply和Outer Apply的區別及用法