2017年9月5日 星期二

【SQL】Derived table, Subquery, CTE, Temporary table, Table variable

這篇主要是面試被考到 CTE,但我實際上不只沒寫過,連聽都沒聽過,查了一下發現暫存資料集的眉眉角角比想像的多很多,所以做一下整理,有誤還請指出。

Derived table & Subquery  
衍生資料表就是具名的子查詢

ex. 查詢俱樂部='內湖',所有人的英文名字
  1. -- Subquery
  2. SELECT [EngFirstName]
  3. FROM [Member] tM
  4. WHERE Id IN
  5. (
  6. SELECT [MemberId]
  7. FROM [MemberClub] tMC
  8. INNER JOIN [Club] tC ON tMC.ClubId = tc.Id
  9. WHERE tc.ChineseAbbr = '內湖'
  10. )
  11.  
  12. -- Derived table
  13. SELECT [EngFirstName]
  14. FROM [Member] tM
  15. INNER JOIN
  16. (
  17. SELECT [MemberId]
  18. FROM [MemberClub] tMC
  19. INNER JOIN [Club] tC ON tMC.ClubId = tc.Id
  20. WHERE tc.ChineseAbbr = '內湖'
  21. ) derived
  22. ON tM.Id = derived.MemberId
兩組會 SELECT 出一樣的結果,但在第二種我們給了子查詢別名,就讓這個子查詢成了衍生資料表。

CTE (Common Table Expressions)
應用上近似於 一次性的檢視表整理過可讀性的衍生表
主要應用是 提高可讀性 與 遞迴產生資料集(樹狀階層式結構)。
  1. WITH cteNeihuMemberIds ([MemberId]) as
  2. (
  3. SELECT [MemberId]
  4. FROM [MemberClub] tMC
  5. INNER JOIN [Club] tC ON tMC.ClubId = tc.Id
  6. WHERE tc.ChineseAbbr = '內湖'
  7. )
  8.  
  9. SELECT [EngFirstName]
  10. FROM [Member] tM
  11. INNER JOIN cteNeihuMemberIds
  12. ON tM.Id = cteNeihuMemberIds.MemberId
  13.  
  14. -- X
  15. -- Can only use one time
  16. SELECT [Name]
  17. FROM [Role] tR
  18. INNER JOIN RoleRecord tRR
  19. ON tR.Id = tRR.RoleId
  20. INNER JOIN cteNeihuMemberIds
  21. ON tRR.MemberId = cteNeihuMemberIds.MemberId

ref: CTE vs subquery;它的強項遞迴查詢: 暗黑執行緒MSDN

Temporary table
  1. CREATE TABLE #tmp (Col1 int, Col2 nvarchar(50));
基本上等同於資料表(有資料庫物件存在 tempdb),叢集、非叢集索引都可以有,可以做 CRUD 操作,跟真的資料表唯一差別是 Session(Connection) 結束會 DROP(如果是 sp 建的,則 sp 結束 DROP),但最好是我們記得自己手動 DROP 它。

Table variable
  1. DECLARE @tmp TABLE (Col1 int, Col2 nvarchar(50));
是 temp table 的簡化版,一樣會有資料庫物件(我本來也以為沒有),可以 CRUD,但沒有非叢集索引(< 2014的版本)和篩選索引(< 2016的版本),它的 scope 就是變數的 life scope,試下面範例
  1. DECLARE @temp TABLE (col1 INT)
  2. INSERT @temp VALUES(1)
  3. SELECT * FROM @temp
  4. GO
  5. SELECT * FROM @temp
關於 GO,延伸閱讀:批次

應用上 table variable 適用於小資料集、少量操作,temp table 適合大資料集、大量操作,table variable 除了語法限制(沒有 TRUNCATE、SELECT INTO等),最佳化也會以小資料集為前提規劃執行計畫。 另外 table variable 不受交易 rollback 的影響。

這部分細節蠻多的,參考:SO(DBA)暗黑執行緒蔡煥麟老師MSDN

沒有留言:

張貼留言