2018年2月7日 星期三

優先由倉庫出貨,如缺貨則改由分店-利用FULL OUTER JOIN特性搭配COALESCE函數應用


本範例將FULL OUTER JOIN搭配COALESCE函數產生出貨調貨報表,以倉庫優先出貨(藍色),如已無庫存,則至其他分店(紅色)調貨,圖示及SQL如下:

SQL
ORACLE
SELECT Inventory.*
   , Store.*
   , COALESCE(Inventory.Prod, Store.Prod) Prod--2.COALESCE(倉庫, 分店)決定優先順序
   , COALESCE(Inventory.Qty,  Store.Qty)  Qty
   , CASE WHEN Inventory.Prod IS NOT NULL THEN '倉庫' ELSE Store.Loc END Loc
FROM
     (
     --優先: 倉庫出貨
     SELECT 'DDR2' Prod, 20 Qty
     FROM DUAL   
     UNION ALL
     SELECT 'DDR3' Prod, 100 Qty
     FROM DUAL
     UNION ALL
     SELECT 'DDR4'  Prod, 300 Qty
     FROM DUAL                
     ) Inventory
     FULL OUTER JOIN--1.FULL OUTER JOIN產生2者最大資料集
     (
      --替代: 無現貨再由各分店調貨
     SELECT 'DDR' Prod, 50 Qty,  '光華店' Loc    
     FROM DUAL   
     UNION ALL
     SELECT 'DDR2' Prod, 10 Qty,  '公館店' Loc    
     FROM DUAL   
     UNION ALL
     SELECT 'DDR4' Prod, 80 Qty,  '站前店' Loc    
     FROM DUAL 
     ) Store 
     ON Inventory.Prod = Store.Prod 
ORDER BY COALESCE(Inventory.Prod, Store.Prod) 
-- 註:COALESCE可改用NVL 
MSSQL
SELECT *
  , COALESCE(Warehouse.Prod, Store.Prod) Prod--2.COALESCE(倉庫, 分店)決定優先順序
  , COALESCE(Warehouse.Qty,  Store.Qty)  Qty
  , CASE WHEN Warehouse.Prod IS NOT NULL THEN '倉庫' ELSE Store.Loc END Loc
FROM --優先: 倉庫出貨
    (VALUES ('DDR2',  20)    
             , ('DDR3', 100)
             , ('DDR4', 300)         
    ) Warehouse (Prod, Qty)
    FULL OUTER JOIN --1.FULL OUTER JOIN產生者最大資料集
       --替代: 無現貨再由各分店調貨
    (VALUES ('DDR', 50,  '光華店')
          , ('DDR2', 10,  '公館店')
          , ('DDR4', 80,  '站前店')            
    ) Store (Prod, Qty, Loc)
       ON Warehouse.Prod = Store.Prod 
ORDER BY COALESCE(Warehouse.Prod, Store.Prod)
--: COALESCE可改用ISNULL函數    
1.  FULL OUTER JOIN產生二者最大資料集
外部連結(Outer Join)則可根據定義的保留資料表(Preserved table)為基礎,外部連結所連結的資料表中,不管資料列是否能配對,所有保留資料表()上的資料均將傳回對於連結表格中無法配對的資料欄位則填入NULL。在此將使用FULL OUTER JOIN即兩個資料表的聯集(最大集合),任何無法與另外資料表匹配的部分傳回NULL值,可參考資料表連結(Table Join)概念》文章所述。

2.  COALESCE()參數位置決定優先順序
前述步驟將產生兩者最大資料集,但無法配對的資料欄位則填入NULL值,資料至少存在於一方,可利用COALESCE函數特性,當第一個參數為NULL時,將以第二個參數取代(置換),因此只需將優先者至於第一個參數即可。COALESCE函數於此範例也可使用ISNULLMSSQL)或NVL(ORACLE)可參考NULL處理應注意事項及常用函數》文章。

沒有留言:

張貼留言