是否有办法摆脱WITH子句(公共表表达式)?这对性能有好处吗?



我有以下代码:

WITH 
SO_Req_ AS 
(
SELECT
SO_REQ.SALESMAN AS Sales_Person, 
SO_REQ.SALES_CAT AS Sales_Category, 
SO_REQ.SO_REQ_ID AS SO_Req__ID, 
SO_REQ.SO_REQ_NO AS SO_Req__No_, 
SO_REQ.ORDER_PLACED_BY AS Order_Placed_By
FROM
ITIMS.SO_REQ SO_REQ
LEFT OUTER JOIN ITIMS.APP_LINK APP_LINK
ON SO_REQ.APP_LINK_ID = APP_LINK.APP_LINK_ID
FULL OUTER JOIN ITIMS.TIMS_APP TIMS_APP
ON TIMS_APP.TIMS_APP_ID = APP_LINK.SRC_TIMS_APP_ID
), 
PROJECT__CR_ AS 
(
SELECT DISTINCT 
PRJ.PROJECT_ID, 
PRJ.PROJECT_CD, 
PRJ.PROJECT_DESC, 
'Y' AS ITIMS_PROJECT, 
ACTIVE_TIMS_SITE_FLAG
FROM
ITIMS.PROJECT PRJ, 
ITIMS.SITE_USER SU 
WHERE 
PRJ.PROJECT_ID = SU.PROJECT_ID
), 
CR_Project AS 
(
SELECT
PROJECT__CR_.PROJECT_CD AS Project_Code, 
PROJECT__CR_.PROJECT_ID AS Project_ID
FROM
PROJECT__CR_
), 
CR_OCTG_Hdr__Adjustment AS 
(
SELECT
CR_ADJ.CR_ADJ_ID AS CR_Adjustment_ID, 
CR_ADJ.TAX_FLAG AS Tax_Flag, 
CR_ADJ.USD_RATE AS Credit_Rate__USD_, 
CR_ADJ.UOM AS Quantity_UOM, 
CR_ADJ.PROCESS_STATE AS CR_Adjustment_Status, 
CR_ADJ.QTY AS Quantity, 
CR_ADJ.ADJ_SIGN AS Adjustment_Sign, 
CR_ADJ.COST_RATE AS Cost_Rate, 
APP_LINK.SRC_REF_2 AS Source_Ref2
FROM
ITIMS.TIMS_APP TIMS_APP
LEFT OUTER JOIN 
ITIMS.APP_LINK APP_LINK
INNER JOIN ITIMS.CR_ADJ CR_ADJ
ON APP_LINK.APP_LINK_ID = CR_ADJ.APP_LINK_ID
ON TIMS_APP.TIMS_APP_ID = APP_LINK.SRC_TIMS_APP_ID
LEFT OUTER JOIN ITIMS.UOM_CONV UOM_CONV__FT___CR_ADJ_
ON 
CR_ADJ.UOM = UOM_CONV__FT___CR_ADJ_.UOM_FROM AND
UOM_CONV__FT___CR_ADJ_.UOM_TO = 'FT'
LEFT OUTER JOIN ITIMS.UOM_CONV UOM_CONV__M___CR_ADJ_
ON 
CR_ADJ.UOM = UOM_CONV__M___CR_ADJ_.UOM_FROM AND
UOM_CONV__M___CR_ADJ_.UOM_TO = 'M' 
WHERE 
APP_LINK.SRC_TIMS_APP_ID = 743
), 
CR_Req__Bill_To AS 
(
SELECT
BIZENT.BIZENT_GRP_CD AS Bill_to_Bizent_Group_Code, 
BIZENT.BIZENT_GRP_NAME AS Bill_to_Bizent_Group_Name, 
BIZENT.BIZENT_CD AS Bill_to_Bizent_Code, 
BIZENT.BIZENT_NAME AS Bill_to_Bizent_Name, 
BIZENT.OUTSIDE_SALESMAN AS Outside_Salesman, 
BIZENT.BIZENT_ID AS Bill_to_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID
), 
CR_Req__Customer AS 
(
SELECT
BIZENT.BIZENT_CD AS Customer_Bizent_Code, 
BIZENT.BIZENT_NAME AS Customer_Bizent_Name, 
BIZENT.BIZENT_ID AS Customer_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID
)
SELECT
'CR' AS SRC,
'ADJ - OCTG HDR' AS ITEM_CLASS,
CR_Req_.PROJECT_ID,
CR_Project.Project_Code, 
CR_Req_.CR_ID, 
CR_OCTG_Hdr__Adjustment.CR_Adjustment_ID, 
CR_Req__Bill_To.Bill_to_Bizent_Group_Code, 
CR_Req__Bill_To.Bill_to_Bizent_Group_Name, 
CR_Req__Customer.Customer_Bizent_Code, 
CR_Req__Customer.Customer_Bizent_Name, 
CR_Req__Bill_To.Bill_to_Bizent_Code, 
CR_Req__Bill_To.Bill_to_Bizent_Name, 
SO_Req_.Sales_Person, 
SO_Req_.Sales_Category, 
CR_Req_.CR_NO, 
CR_Req_.DATE_CREATED, 
CR_Req_.ACCT_PERIOD, 
SO_Req_.SO_Req__ID, 
SO_Req_.SO_Req__No_, 
SO_Req_.Order_Placed_By, 
CR_Req_.DISC_TAKEN_FLAG, 
CR_Req_.AFE_NO, 
CR_Req__Bill_To.Outside_Salesman, 
CR_Req_.RETURN_DATE, 
CR_OCTG_Hdr__Adjustment.Tax_Flag, 
CR_OCTG_Hdr__Adjustment.Credit_Rate__USD_, 
CR_OCTG_Hdr__Adjustment.Quantity_UOM, 
CR_OCTG_Hdr__Adjustment.Quantity, 
CR_OCTG_Hdr__Adjustment.Adjustment_Sign, 
ifnull((CR_OCTG_Hdr__Adjustment.Cost_Rate * CR_OCTG_Hdr__Adjustment.Quantity) * CASE 
WHEN CR_OCTG_Hdr__Adjustment.Adjustment_Sign LIKE 'A' THEN -1
ELSE 1
END, 0) COST_USD
FROM
SO_Req_
LEFT OUTER JOIN ITIMS.INVC Invoice_Req_
ON SO_Req_.SO_Req__ID = Invoice_Req_.SO_REQ_ID
LEFT OUTER JOIN ITIMS.CR CR_Req_
ON Invoice_Req_.INVC_ID = CR_Req_.INVC_ID
FULL OUTER JOIN CR_Project
ON CR_Project.Project_ID = CR_Req_.PROJECT_ID
LEFT OUTER JOIN ITIMS.CR_OCTG_HDR CR_OCTG_Hdr_
ON CR_Req_.CR_ID = CR_OCTG_Hdr_.CR_ID
LEFT OUTER JOIN CR_OCTG_Hdr__Adjustment
ON CR_OCTG_Hdr_.CR_OCTG_HDR_ID = CR_OCTG_Hdr__Adjustment.Source_Ref2
FULL OUTER JOIN CR_Req__Bill_To
ON CR_Req__Bill_To.Bill_to_Bizent_ID = CR_Req_.BILLTO_BIZENT_ID
FULL OUTER JOIN CR_Req__Customer
ON CR_Req__Customer.Customer_Bizent_ID = CR_Req_.CUST_BIZENT_ID 
WHERE 
NOT ( CR_OCTG_Hdr__Adjustment.CR_Adjustment_ID IS NULL ) AND
NOT ( CR_OCTG_Hdr__Adjustment.CR_Adjustment_Status LIKE 'X' ) AND
NOT ( CR_Req_.PROCESS_STATE LIKE 'X' )

这里的问题是,如果有一种方法来摆脱使用WITH子句创建的所有cte(公共表表达式),并获得相同的结果?此外,它会对性能产生一些有益的影响吗?

我一直在尝试做这个任务,但是当我试图打开这个cte时,我遇到了麻烦。

非常感谢你的帮助,真的很感激!

所以简单的答案是肯定的!CTE提供了两个函数来分割内容,并允许以表达式的形式选择公共表。

WITH cte_name AS (
SELECT struff 
FROM tables
)
SELECT stuff 
FROM tables
JOIN cte_name

等于:

SELECT stuff 
FROM tables
JOIN (
SELECT struff 
FROM tables
)

这只是一个剪切-粘贴。

现在如果您多次使用CTE表,那么在大多数DB中,该公共子表达式仅求值一次。在Snowflake中,如果读IO比完成CTE工作所需的CPU慢,那么这可能会减慢速度,两个并行读可能会读得更少,因此运行得更快。和所有事情一样,测试。

所以对于你的代码,你所有的CTE都可以展开,这对速度没有任何影响。我相信这会让你的代码更难以读懂。

所以从我将如何重构你现有的代码开始:

WITH so_req_ AS (
SELECT
s.salesman AS sales_person, 
s.sales_cat AS sales_category, 
s.so_req_id AS so_req__id, 
s.so_req_no AS so_req__no_, 
s.order_placed_by AS order_placed_by
FROM itims.so_req AS s
LEFT OUTER JOIN itims.app_link as a
ON s.app_link_id = a.app_link_id
FULL OUTER JOIN itims.tims_app AS t
ON t.tims_app_id = a.src_tims_app_id

), project__cr_ AS (
SELECT DISTINCT 
prj.project_id, 
prj.project_cd, 
prj.project_desc, 
'Y' AS itims_project, 
active_tims_site_flag
FROM itims.project AS prj
CROSS JOIN itims.site_user AS su 
WHERE prj.project_id = su.project_id

), cr_project AS (
SELECT
p.project_cd AS project_code, 
p.project_id AS project_id
FROM project__cr_ AS p

), cr_octg_hdr__adjustment AS (
SELECT
c.cr_adj_id AS cr_adjustment_id, 
c.tax_flag AS tax_flag, 
c.usd_rate AS credit_rate__usd_, 
c.uom AS quantity_uom, 
c.process_state AS cr_adjustment_status, 
c.qty AS quantity, 
c.adj_sign AS adjustment_sign, 
c.cost_rate AS cost_rate, 
al.src_ref_2 AS source_ref2
FROM itims.tims_app AS t
LEFT OUTER JOIN itims.app_link AS al
INNER JOIN itims.cr_adj AS c
ON al.app_link_id = c.app_link_id
ON t.tims_app_id = al.src_tims_app_id
LEFT OUTER JOIN itims.uom_conv AS u1
ON c.uom = u1.uom_from 
AND u1.uom_to = 'FT'
LEFT OUTER JOIN itims.uom_conv AS u2
ON c.uom = u2.uom_from 
AND u2.uom_to = 'M' 
WHERE 
al.src_tims_app_id = 743

), cr_req__bill_to AS (
SELECT
BIZENT.BIZENT_GRP_CD AS Bill_to_Bizent_Group_Code, 
BIZENT.BIZENT_GRP_NAME AS Bill_to_Bizent_Group_Name, 
BIZENT.BIZENT_CD AS Bill_to_Bizent_Code, 
BIZENT.BIZENT_NAME AS Bill_to_Bizent_Name, 
BIZENT.OUTSIDE_SALESMAN AS Outside_Salesman, 
BIZENT.BIZENT_ID AS Bill_to_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID
), cr_req__customer AS (
SELECT
BIZENT.BIZENT_CD AS Customer_Bizent_Code, 
BIZENT.BIZENT_NAME AS Customer_Bizent_Name, 
BIZENT.BIZENT_ID AS Customer_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID

)
SELECT
'CR' AS SRC,
'ADJ - OCTG HDR' AS ITEM_CLASS,
CR_Req_.PROJECT_ID,
CR_Project.Project_Code, 
CR_Req_.CR_ID, 
CR_OCTG_Hdr__Adjustment.CR_Adjustment_ID, 
CR_Req__Bill_To.Bill_to_Bizent_Group_Code, 
CR_Req__Bill_To.Bill_to_Bizent_Group_Name, 
CR_Req__Customer.Customer_Bizent_Code, 
CR_Req__Customer.Customer_Bizent_Name, 
CR_Req__Bill_To.Bill_to_Bizent_Code, 
CR_Req__Bill_To.Bill_to_Bizent_Name, 
s.Sales_Person, 
s.Sales_Category, 
CR_Req_.CR_NO, 
CR_Req_.DATE_CREATED, 
CR_Req_.ACCT_PERIOD, 
s.SO_Req__ID, 
s.SO_Req__No_, 
s.Order_Placed_By, 
CR_Req_.DISC_TAKEN_FLAG, 
CR_Req_.AFE_NO, 
CR_Req__Bill_To.Outside_Salesman, 
CR_Req_.RETURN_DATE, 
CR_OCTG_Hdr__Adjustment.Tax_Flag, 
CR_OCTG_Hdr__Adjustment.Credit_Rate__USD_, 
CR_OCTG_Hdr__Adjustment.Quantity_UOM, 
CR_OCTG_Hdr__Adjustment.Quantity, 
CR_OCTG_Hdr__Adjustment.Adjustment_Sign, 
ifnull((CR_OCTG_Hdr__Adjustment.Cost_Rate * CR_OCTG_Hdr__Adjustment.Quantity) * CASE 
WHEN CR_OCTG_Hdr__Adjustment.Adjustment_Sign LIKE 'A' THEN -1
ELSE 1
END, 0) COST_USD
FROM so_req_ AS s
LEFT OUTER JOIN itims.invc AS invoice_req_
ON s.so_req__id = invoice_req_.so_req_id
LEFT OUTER JOIN itims.cr AS cr_req_
ON Invoice_Req_.INVC_ID = CR_Req_.INVC_ID
FULL OUTER JOIN CR_Project
ON CR_Project.Project_ID = CR_Req_.PROJECT_ID
LEFT OUTER JOIN ITIMS.CR_OCTG_HDR CR_OCTG_Hdr_
ON CR_Req_.CR_ID = CR_OCTG_Hdr_.CR_ID
LEFT OUTER JOIN CR_OCTG_Hdr__Adjustment
ON CR_OCTG_Hdr_.CR_OCTG_HDR_ID = CR_OCTG_Hdr__Adjustment.Source_Ref2
FULL OUTER JOIN CR_Req__Bill_To
ON CR_Req__Bill_To.Bill_to_Bizent_ID = CR_Req_.BILLTO_BIZENT_ID
FULL OUTER JOIN CR_Req__Customer
ON CR_Req__Customer.Customer_Bizent_ID = CR_Req_.CUST_BIZENT_ID 
WHERE 
NOT ( CR_OCTG_Hdr__Adjustment.CR_Adjustment_ID IS NULL ) AND
NOT ( CR_OCTG_Hdr__Adjustment.CR_Adjustment_Status LIKE 'X' ) AND
NOT ( CR_Req_.PROCESS_STATE LIKE 'X' )

变成了(我必须多混叠一些东西):

SELECT
'CR' AS SRC,
'ADJ - OCTG HDR' AS ITEM_CLASS,
CR_Req_.PROJECT_ID,
cp.Project_Code, 
CR_Req_.CR_ID, 
cha.CR_Adjustment_ID, 
cbt.Bill_to_Bizent_Group_Code, 
cbt.Bill_to_Bizent_Group_Name, 
rc.Customer_Bizent_Code, 
rc.Customer_Bizent_Name, 
cbt.Bill_to_Bizent_Code, 
cbt.Bill_to_Bizent_Name, 
s.Sales_Person, 
s.Sales_Category, 
CR_Req_.CR_NO, 
CR_Req_.DATE_CREATED, 
CR_Req_.ACCT_PERIOD, 
s.SO_Req__ID, 
s.SO_Req__No_, 
s.Order_Placed_By, 
CR_Req_.DISC_TAKEN_FLAG, 
CR_Req_.AFE_NO, 
cbt.Outside_Salesman, 
CR_Req_.RETURN_DATE, 
cha.Tax_Flag, 
cha.Credit_Rate__USD_, 
cha.Quantity_UOM, 
cha.Quantity, 
cha.Adjustment_Sign, 
ifnull((cha.Cost_Rate * cha.Quantity) * CASE 
WHEN cha.Adjustment_Sign LIKE 'A' THEN -1
ELSE 1
END, 0) COST_USD
FROM (
SELECT
s.salesman AS sales_person, 
s.sales_cat AS sales_category, 
s.so_req_id AS so_req__id, 
s.so_req_no AS so_req__no_, 
s.order_placed_by AS order_placed_by
FROM itims.so_req AS s
LEFT OUTER JOIN itims.app_link as a
ON s.app_link_id = a.app_link_id
FULL OUTER JOIN itims.tims_app AS t
ON t.tims_app_id = a.src_tims_app_id

) AS s
LEFT OUTER JOIN itims.invc AS invoice_req_
ON s.so_req__id = invoice_req_.so_req_id
LEFT OUTER JOIN itims.cr AS cr_req_
ON Invoice_Req_.INVC_ID = CR_Req_.INVC_ID
FULL OUTER JOIN (
SELECT
p.project_cd AS project_code, 
p.project_id AS project_id
FROM (
SELECT DISTINCT 
prj.project_id, 
prj.project_cd, 
prj.project_desc, 
'Y' AS itims_project, 
active_tims_site_flag
FROM itims.project AS prj
CROSS JOIN itims.site_user AS su 
WHERE prj.project_id = su.project_id            
) AS p  
) as cp
ON cp.Project_ID = CR_Req_.PROJECT_ID
LEFT OUTER JOIN ITIMS.CR_OCTG_HDR CR_OCTG_Hdr_
ON CR_Req_.CR_ID = CR_OCTG_Hdr_.CR_ID
LEFT OUTER JOIN (
SELECT
c.cr_adj_id AS cr_adjustment_id, 
c.tax_flag AS tax_flag, 
c.usd_rate AS credit_rate__usd_, 
c.uom AS quantity_uom, 
c.process_state AS cr_adjustment_status, 
c.qty AS quantity, 
c.adj_sign AS adjustment_sign, 
c.cost_rate AS cost_rate, 
al.src_ref_2 AS source_ref2
FROM itims.tims_app AS t
LEFT OUTER JOIN itims.app_link AS al
INNER JOIN itims.cr_adj AS c
ON al.app_link_id = c.app_link_id
ON t.tims_app_id = al.src_tims_app_id
LEFT OUTER JOIN itims.uom_conv AS u1
ON c.uom = u1.uom_from 
AND u1.uom_to = 'FT'
LEFT OUTER JOIN itims.uom_conv AS u2
ON c.uom = u2.uom_from 
AND u2.uom_to = 'M' 
WHERE 
al.src_tims_app_id = 743

) as cha
ON CR_OCTG_Hdr_.CR_OCTG_HDR_ID = cha.Source_Ref2
FULL OUTER JOIN (
SELECT
BIZENT.BIZENT_GRP_CD AS Bill_to_Bizent_Group_Code, 
BIZENT.BIZENT_GRP_NAME AS Bill_to_Bizent_Group_Name, 
BIZENT.BIZENT_CD AS Bill_to_Bizent_Code, 
BIZENT.BIZENT_NAME AS Bill_to_Bizent_Name, 
BIZENT.OUTSIDE_SALESMAN AS Outside_Salesman, 
BIZENT.BIZENT_ID AS Bill_to_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID
) as cbt
ON cbt.Bill_to_Bizent_ID = CR_Req_.BILLTO_BIZENT_ID
FULL OUTER JOIN (
SELECT
BIZENT.BIZENT_CD AS Customer_Bizent_Code, 
BIZENT.BIZENT_NAME AS Customer_Bizent_Name, 
BIZENT.BIZENT_ID AS Customer_Bizent_ID
FROM
ITIMS.BIZENT_GRP BIZENT_GRP
LEFT OUTER JOIN ITIMS.BIZENT BIZENT
ON BIZENT_GRP.BIZENT_GRP_ID = BIZENT.BIZENT_GRP_ID

) as rc 
ON rc.Customer_Bizent_ID = CR_Req_.CUST_BIZENT_ID 
WHERE 
NOT ( cha.CR_Adjustment_ID IS NULL ) AND
NOT ( cha.CR_Adjustment_Status LIKE 'X' ) AND
NOT ( CR_Req_.PROCESS_STATE LIKE 'X' )

可读性差很多。并且会有完全相同的性能

相关内容

  • 没有找到相关文章