星期五, 3月 18, 2011

UNION

UNION 將兩個或更多查詢的結果集結合成單一結果集(縱向連結資料),個人覺得 UNION 最好用的地方在於連接歷史資料庫,尤其是習慣把每一年資料拆成一個 Table 來整理,EX:Order98、Order99。

    SQL UNION 使用限制:
  • 欄位數目和順序需要一致
  • 欄位資料型態必須相容(隱含式轉換)
    VFP UNION 使用限制:
  • 除了上述限制外,在 8.0 和 9.0 版本裡假如資料行有 Memo 資料型態,一定要用 UNION ALL,用 UNION 會錯誤,8.0 之前版本則是沒有這個限制。
    SQL、VFP UNION 使用上需要注意的地方:
  • UNION 和 UNION ALL的差異:UNION 會自動過濾重複資料,而 UNION ALL 則是會把全部資料都列出來;因為 UNION 會過濾重覆資料,所以在效率上,UNION ALL會比較快一些。
  • 欄位名稱以第一個資料集為依據。
  • Order By 必須放在整個 T-SQL 語法的最後。
-- 建立範例資料
DECLARE @NY table (EmployeeID char(4),Employee char(8),Birthday datetime)
DECLARE @TW table (EmployeeID char(4),Employee char(8),Birthday datetime)
 
-- Ray 和 Doris 這兩個人名,同時存在 @TW 和 @NY 中  
INSERT INTO @NY VALUES('NY01','Emma','19860606')
INSERT INTO @NY VALUES('NY02','Ray','19840404')
INSERT INTO @NY VALUES('NY03','Doris','19870707')
INSERT INTO @NY VALUES('NY04','Peggie','19890909')
INSERT INTO @NY VALUES('NY05','Angel','19810101')
INSERT INTO @TW VALUES('TW01','Terry','19901010')
INSERT INTO @TW VALUES('TW02','Ray','19820202')
INSERT INTO @TW VALUES('TW03','Doris','19830303')
INSERT INTO @TW VALUES('TW04','Fanny','19880808')
INSERT INTO @TW VALUES('TW05','Jarry','19850505')

  • UNION 和 UNION ALL 產生結果比較
-- UNION 把重覆資料過濾掉,並對資料進行排序
SELECT Employee FROM @NY
UNION
SELECT Employee FROM @TW

-- UNION ALL 列出全部資料,不對資料進行排序
SELECT Employee FROM @NY
UNION ALL
SELECT Employee FROM @TW
UNION 1
UNION 2
之前因為不知道 UNION 和 UNION ALL 兩者差異,導致抓出來資料不如預期,找了好久才發現兩者差異。
  • 從執行計畫來看 UNION 和 UNION ALL 效能問題 
可以發現 UNION 刪除重復資料會對資料進行排序(相異排序),也因此造成效能降低。
    UNION 3
    • 欄位名稱使用
    SELECT 
      EmployeeID AS 員工編號 , 
      Employee AS 員工名稱 , 
      Birthday AS 生日 -- 以第一個結果集的欄位名稱為主
    FROM @NY
    UNION ALL
    SELECT 
      EmployeeID , 
      Employee , 
      Birthday
    FROM @TW
    
    UNION 4
    • Order By 應用說明
    -- 錯誤用法
    SELECT EmployeeID,Employee,Birthday
    FROM @NY
    ORDER BY Birthday -- 不可以放在資料集中
    UNION ALL
    SELECT EmployeeID,Employee,Birthday
    FROM @TW
    
    -- 正確正法
    SELECT EmployeeID,Employee,Birthday
    FROM @NY
    UNION ALL
    SELECT EmployeeID,Employee,Birthday
    FROM @TW
    ORDER BY Birthday -- 必須放在整個 T-SQL 語法最後
    
    • 控制 UNION 中,每個資料集呈現順序
    上述有提到,UNION 動作時,會針對資料進行排序,導致最後排序結果,不符合實際需求,可以新增一個排序欄位,讓 Order By 根據此欄位排序,來達到控制資料集排序。
    -- 會依據 Employee 第一個字母大小進行排序
    SELECT Employee
    FROM @TW
    WHERE Employee = 'Jarry'
    UNION 
    SELECT Employee
    FROM @TW
    WHERE Employee = 'Doris'
    UNION 
    SELECT Employee
    FROM @NY
    WHERE Employee = 'Emma'
    UNION 
    SELECT Employee
    FROM @NY
    WHERE Employee = 'Angel'
    
    -- 根據自訂欄位來排序
    SELECT Employee,4 AS SetOrderBy -- 自訂 SetOrderBy 欄位
    FROM @TW
    WHERE Employee = 'Jarry'
    UNION 
    SELECT Employee,3
    FROM @TW
    WHERE Employee = 'Doris'
    UNION 
    SELECT Employee,1
    FROM @NY
    WHERE Employee = 'Emma'
    UNION 
    SELECT Employee,2
    FROM @NY
    WHERE Employee = 'Angel'
    Order by SetOrderBy
    
    UNION 5

    沒有留言:

    張貼留言