馬哈魚資料血緣分析器是一個分析資料血緣關係的平臺,可以線上直接遞交 SQL 語句進行分析,也可以選擇連線指定資料庫獲取 metadata、從本地上傳檔案目錄、或從指定 git 倉庫獲取指令碼進行分析。

本文介紹如果利用馬哈魚來分析SQL的case-when語句中欄位依賴關係。

一個簡單的Case

考慮如下SQL:

select
case when a.kamut=1 and b.teur IS null
then 'no locks'
when a.kamut=1
then b.teur
else 'locks'
end teur
from tbl a left join TT b on (a.key=b.key)

SQL的返回欄位 teur,它的值直接於case-when的計算結果。

在馬哈魚的設計理念裡,case-when被認為是一種特殊的function,但又不同於普通的function,它並沒有argument。馬哈魚直接分析case when中的when、then、else子句。

其中,then、else子句的欄位直接作為返回結果提供給teur,因此毫無疑問,then、else子句的欄位和teur是一個fdd關係。需要考慮的是when子句,teur的結果是間接依賴when子句,滿足不同的when子句,會返回不同的then結果,這會影響到最終teur欄位的返回值。因此:

when --> fdr --> then --> fdd --> resultset column

此處的when子句非常類似where語句,只不過影響的是then子句,而不是直接影響resultset column。

如圖所示:

teur和兩個when子句:a.kamut=1 and b.teur IS null, a.kamut=1,產生了fdr關係,因此

a.kamut --> fdr -->teur1 --> fdr --> teurb.teur --> fdr --> teur

teur和2個then子句及else子句產生了fdd關係,因此

'no locks' --> fdd --> teurb.teur --> fdd --> teur'locks' --> fdd --> teur

其中b.teur和teur直接同時存在了fdd和fdr關係,由於fdd關係優先順序高於fdr關係,因此在graph中,只顯示出了fdd關係。

稍微複雜一些的Case,巢狀case-when語句

CREATE VIEW FACT_PRCU_FLDR AS
SELECT
PRCU.PRCU_ID AS PRCU_FLDR_ID,
CONCAT(PRCU.PRCU_TYP_ID,'^','^') AS PRCU_FLDR_TYP_ID,
CONCAT('^',PRCU.BUYR_ID) AS BUYR_STAFF_ID,
CONCAT('^',PRCU.MGR_ID) AS MGR_STAFF_ID,
CONCAT(PRCU.BUYR_TEAM,'^') AS BUYR_TEAM_STAFF_ID,
PRCU.CMPLX_CD AS PRCU_CMPLX_ID,
PRCU.RNG_CD AS PRCU_RNG_ID,
(CASE WHEN PRCU.NO_ST IS NOT NULL AND PRCU.NO_ST_COMPLETE IS NOT NULL
THEN (PRCU.NO_ST - PRCU.NO_ST_COMPLETE)
END) AS NO_ORD_ST,
(CASE WHEN PRCU.COMPLETE_FL=1 THEN 'Final'
WHEN (CASE WHEN PRCU.NO_ST IS NOT NULL AND PRCU.NO_ST_COMPLETE IS NOT NULL
THEN (PRCU.NO_ST - PRCU.NO_ST_COMPLETE)
END) > 0 THEN 'Alert!'
ELSE 'Ok'
END) AS FLDR_COMPLETE,
PRCU.PRCU_ID,
PRCU.PRCU_TYP_ID,
PRCU.PRCU_DSCR,
PRCU.EXPT_COMPLETE_DT,
PRCU.CLSD_DT,
PRCU.BUYR_ID,
PRCU.MGR_ID,
PRCU.BUYR_TEAM,
PRCU.CMPLX_CD,
PRCU.RNG_CD,
PRCU.COMPLETE_FL,
COALESCE(PRCU.NO_ST,0) AS NO_ST,
COALESCE(PRCU.NO_ST_COMPLETE, 0) AS NO_ST_COMPLETE,
CVLST.CVL_PRCU_ST_ID_DV AS "LAST_ST_COMPLETE",
COALESCE(PRCU.TOT_AMT, 0) AS TOT_AMT,
PRCU.TBL_LAST_DT,
PRCU.PRCU_TITLE,
(SELECT MIN(CREA_DT) FROM R_PRCU_ST ST WHERE PRCU.PRCU_ID=ST.PRCU_ID AND ST.CREA_DT IS NOT NULL) FLDR_CREA_DT,
COALESCE(PRCU.ORGNL_PRCU_TOT_AM, 0) AS ORGNL_PRCU_TOT_AM,
CONCAT(PRCU.EXT_STOR_UNID,'^R_PRCU_ID')AS EXT_ID,
/*INSIGHT_LITE_COLUMNS_STRT*/
0 AS REC_ST,
PRCU.TBL_LAST_DT AS LAST_PROCESS_DT
/*INSIGHT_LITE_COLUMNS_END*/
/*INSIGHT_COLUMNS_STRTPRCU.REC_ST,PRCU.LAST_PROCESS_DTINSIGHT_COLUMNS_END*/
FROM
R_PRCU_ID PRCU LEFT OUTER JOIN CVL_PRCU_ST_ID CVLST ON
PRCU.LAST_ST_COMPLETE = CVLST.CVL_PRCU_ST_ID_SV

檢視其中的case-when語句

(CASE WHEN PRCU.COMPLETE_FL=1 THEN 'Final'
WHEN (CASE WHEN PRCU.NO_ST IS NOT NULL AND PRCU.NO_ST_COMPLETE IS NOT NULL
THEN (PRCU.NO_ST - PRCU.NO_ST_COMPLETE)
END) > 0 THEN 'Alert!'
ELSE 'Ok'
END) AS FLDR_COMPLETE

可以看到ResultSet Column FLDR_COMPLETE 被一個case-when語句影響,而其中的第二個When子句又包含了一個case-when語句。

當case-when語句整體作為when子句時,這個子句的fdd關係,實際上是外層when子句fdr關係的一部分,即:

then -->fdd-->when-->fdr-->FLDR_COMPLETE

因此內層case-when的then子句和resultset column FLDR_COMPLETE的關係是fdr關係,而不是fdd關係。

如圖所示,最終影響FLDR_COMPLETE的fdd欄位,僅有外層case-when的then語句和else語句,其他的都顯示為fdr關係。

以上就是對馬哈魚分析case-when語句的處理流程介紹,關於馬哈魚的等多功能,請參考下面連結:

參考

馬哈魚資料血緣關係分析工具中文網站: https://www.sqlflow.cn

馬哈魚資料血緣關係分析工具線上使用: https://sqlflow.gudusoft.com