我下面有某人写的查询(数据库是Microsoft SQL Server 2017)。我无权访问数据库来创建索引等。因此,我唯一能做的就是尽可能有效地优化下面的查询。
我的查询是
我可以在内部查询中使用Case和WHEN吗?目前,我还在尝试使用内部联接删除嵌套查询。
对于以下查询,我们将不胜感激。我不是要给出最终的优化查询,而是要提出以下查询的具体建议。
WITH ChildPremiumCTE (COVER_PREMIUM_SET_ID,POLICY_ID, ADDRESS_ID, STATUS_CODE,COVER_PREMIUM_MODEL_ID, SUB_PRODUCT_REF
, COVER_PREMIUM_MODEL_REF, DESCRIPTION, PREMIUM_LEVEL_CODE
, PREMIUM_PAYABLE, PREMIUM_DUE, COMMISSION_GST, COMMISSION, COMMISSION_TOTAL,TERRORISM_GST
, TERRORISM_RI, STAMP_DUTY, GST, FSL
, MODIFIED_PREMIUM, TECHNICAL_PREMIUM, BASE_PREMIUM
, PREMIUM_PAYABLE_TERM, PREMIUM_DUE_TERM, COMMISSION_GST_TERM
, COMMISSION_TERM, COMMISSION_TOTAL_TERM, TERRORISM_GST_TERM
, TERRORISM_RI_TERM, STAMP_DUTY_TERM, GST_TERM, FSL_TERM
, MODIFIED_PREMIUM_TERM, TECHNICAL_PREMIUM_TERM, BASE_PREMIUM_TERM
, PREMIUM_PAYABLE_ANNUALISED, PREMIUM_DUE_ANNUALISED, COMMISSION_GST_ANNUALISED
, COMMISSION_ANNUALISED, COMMISSION_TOTAL_ANNUALISED, TERRORISM_GST_ANNUALISED
, TERRORISM_RI_ANNUALISED, STAMP_DUTY_ANNUALISED, GST_ANNUALISED
, FSL_ANNUALISED, MODIFIED_PREMIUM_ANNUALISED, TECHNICAL_PREMIUM_ANNUALISED
, BASE_PREMIUM_ANNUALISED)
AS (SELECT CPP.COVER_PREMIUM_SET_ID
, CPS.POLICY_ID
, CASE WHEN CPS.PREMIUM_LEVEL_CODE = 'PREMITEM' THEN SS.ADDRESS_ID ELSE AD.ADDRESS_ID END ADDRESS_ID
, SS.STATUS_CODE
, COALESCE(CPM.COVER_PREMIUM_MODEL_ID, 0) COVER_PREMIUM_MODEL_ID
, CASE WHEN CPS.PREMIUM_LEVEL_CODE = 'POLSUM' THEN 'POLICY_SUMMARY'
ELSE CASE WHEN CPS.PREMIUM_LEVEL_CODE = 'SITSUM' THEN 'SITUATION_SUMMARY' ELSE CPS.SUB_PRODUCT_REF END END SUB_PRODUCT_REF
, CPS.COVER_PREMIUM_MODEL_REF
, CPS.DESCRIPTION
, CPS.PREMIUM_LEVEL_CODE
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_PAYABLE' THEN CPP.TRANSACTION_AMOUNT END) PREMIUM_PAYABLE
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_DUE' THEN CPP.TRANSACTION_AMOUNT END) PREMIUM_DUE
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_GST' THEN CPP.TRANSACTION_AMOUNT END) COMMISSION_GST
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION' THEN CPP.TRANSACTION_AMOUNT END) COMMISSION
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_TOTAL' THEN CPP.TRANSACTION_AMOUNT END) COMMISSION_TOTAL
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_GST' THEN CPP.TRANSACTION_AMOUNT END) TERRORISM_GST
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_RI' THEN CPP.TRANSACTION_AMOUNT END) TERRORISM_RI
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'STAMP_DUTY' THEN CPP.TRANSACTION_AMOUNT END) STAMP_DUTY
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'GST' THEN CPP.TRANSACTION_AMOUNT END) GST
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'FSL' THEN CPP.TRANSACTION_AMOUNT END) FSL
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'MODIFIED_PREMIUM' THEN CPP.TRANSACTION_AMOUNT END) MODIFIED_PREMIUM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TECHNICAL_PREMIUM' THEN CPP.TRANSACTION_AMOUNT END) TECHNICAL_PREMIUM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'BASE_PREMIUM' THEN CPP.TRANSACTION_AMOUNT END) BASE_PREMIUM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_PAYABLE' THEN CPP.TERM_AMOUNT END) PREMIUM_PAYABLE_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_DUE' THEN CPP.TERM_AMOUNT END) PREMIUM_DUE_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_GST' THEN CPP.TERM_AMOUNT END) COMMISSION_GST_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION' THEN CPP.TERM_AMOUNT END) COMMISSION_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_TOTAL' THEN CPP.TERM_AMOUNT END) COMMISSION_TOTAL_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_GST' THEN CPP.TERM_AMOUNT END) TERRORISM_GST_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_RI' THEN CPP.TERM_AMOUNT END) TERRORISM_RI_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'STAMP_DUTY' THEN CPP.TERM_AMOUNT END) STAMP_DUTY_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'GST' THEN CPP.TERM_AMOUNT END) GST_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'FSL' THEN CPP.TERM_AMOUNT END) FSL_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'MODIFIED_PREMIUM' THEN CPP.TERM_AMOUNT END) MODIFIED_PREMIUM_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TECHNICAL_PREMIUM' THEN CPP.TERM_AMOUNT END) TECHNICAL_PREMIUM_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'BASE_PREMIUM' THEN CPP.TERM_AMOUNT END) BASE_PREMIUM_TERM
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_PAYABLE' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) PREMIUM_PAYABLE_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'PREMIUM_DUE' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) PREMIUM_DUE_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_GST' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) COMMISSION_GST_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) COMMISSION_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'COMMISSION_TOTAL' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) COMMISSION_TOTAL_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_GST' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) TERRORISM_GST_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TERRORISM_RI' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) TERRORISM_RI_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'STAMP_DUTY' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) STAMP_DUTY_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'GST' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) GST_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'FSL' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) FSL_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'MODIFIED_PREMIUM' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) MODIFIED_PREMIUM_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'TECHNICAL_PREMIUM' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) TECHNICAL_PREMIUM_ANNUALISED
, MAX(CASE WHEN CPP.PREMIUM_MODEL_PART_REF = 'BASE_PREMIUM' THEN CPP.FUTURE_ANNUALISED_AMOUNT END) BASE_PREMIUM_ANNUALISED
FROM COVER_PREMIUM_SET As CPS
LEFT JOIN SITUATION_SECTION As SS ON CPS.POLICY_ID = SS.POLICY_ID
AND CPS.SITUATION_SECTION_REF = SS.SITUATION_SECTION_REF
LEFT JOIN COVER_PREMIUM_PART As CPP ON CPS.COVER_PREMIUM_SET_ID = CPP.COVER_PREMIUM_SET_ID
LEFT JOIN ADDRESS As AD ON CPS.POLICY_ID = AD.POLICY_ID
AND AD.ADDRESS_REF = CPS.ENTITY_INSTANCE_REF
AND CPS.PREMIUM_LEVEL_CODE IN ('SITSUM', 'SUBPRODSUM')
LEFT JOIN COVER_PREMIUM_MODEL As CPM ON CPS.COVER_PREMIUM_MODEL_REF = CPM.COVER_PREMIUM_MODEL_REF
GROUP BY CPP.COVER_PREMIUM_SET_ID,
CPS.POLICY_ID,
CPS.DESCRIPTION,
CPS.PREMIUM_LEVEL_CODE,
CPS.COVER_PREMIUM_MODEL_REF,
CPS.SUB_PRODUCT_REF,
CPM.COVER_PREMIUM_MODEL_ID,
SS.SITUATION_SECTION_ID,
SS.ADDRESS_ID,
SS.STATUS_CODE,
CPS.ENTITY_INSTANCE_REF,
AD.ADDRESS_ID )
select * from (SELECT
0 AS COVER_PREMIUM_SET_ID
, a1.POLICY_ID
, a1.ADDRESS_ID
, a1.STATUS_CODE
, CPM_CHILD.PARENT_ID AS COVER_PREMIUM_MODEL_ID
, CASE WHEN CPM.PREMIUM_LEVEL_CODE = 'POLSUM' THEN 'POLICY_SUMMARY'
ELSE CASE WHEN CPM.PREMIUM_LEVEL_CODE = 'SITSUM' THEN 'SITUATION_SUMMARY' ELSE a1.SUB_PRODUCT_REF END END SUB_PRODUCT_REF
, CPM.COVER_PREMIUM_MODEL_REF
, CPM.NAME AS Description
, CPM.PREMIUM_LEVEL_CODE AS PREMIUM_LEVEL_CODE
, sum(a1.PREMIUM_PAYABLE) PREMIUM_PAYABLE
, sum(a1.PREMIUM_DUE) PREMIUM_DUE
, sum(a1.COMMISSION_GST) COMMISSION_GST
, sum(a1.COMMISSION) COMMISSION
, sum(a1.COMMISSION_TOTAL) COMMISSION_TOTAL,sum(a1.TERRORISM_GST) TERRORISM_GST
, sum(a1.TERRORISM_RI) TERRORISM_RI, sum(a1.STAMP_DUTY) STAMP_DUTY,sum(a1.GST ) GST, sum(a1.FSL ) FSL
, sum(a1.MODIFIED_PREMIUM ) MODIFIED_PREMIUM, sum(a1.TECHNICAL_PREMIUM ) TECHNICAL_PREMIUM, sum(a1.BASE_PREMIUM ) BASE_PREMIUM
, sum(a1.PREMIUM_PAYABLE_TERM) PREMIUM_PAYABLE_TERM, sum(a1.PREMIUM_DUE_TERM ) PREMIUM_DUE_TERM
, sum(a1.COMMISSION_GST_TERM ) COMMISSION_GST_TERM, sum(a1.COMMISSION_TERM ) COMMISSION_TERM
, sum(a1.COMMISSION_TOTAL_TERM ) COMMISSION_TOTAL_TERM, sum(a1.TERRORISM_GST_TERM ) TERRORISM_GST_TERM
, sum(a1.TERRORISM_RI_TERM ) TERRORISM_RI_TERM, sum(a1.STAMP_DUTY_TERM ) STAMP_DUTY_TERM
, sum(a1.GST_TERM ) GST_TERM, sum(a1.FSL_TERM ) FSL_TERM, sum(a1.MODIFIED_PREMIUM_TERM ) MODIFIED_PREMIUM_TERM
, sum(a1.TECHNICAL_PREMIUM_TERM ) TECHNICAL_PREMIUM_TERM, sum(a1.BASE_PREMIUM_TERM ) BASE_PREMIUM_TERM
, sum(a1.PREMIUM_PAYABLE_ANNUALISED) PREMIUM_PAYABLE_ANNUALISED, sum(a1.PREMIUM_DUE_ANNUALISED ) PREMIUM_DUE_ANNUALISED
, sum(a1.COMMISSION_GST_ANNUALISED ) COMMISSION_GST_ANNUALISED, sum(a1. COMMISSION_ANNUALISED ) COMMISSION_ANNUALISED
, sum(a1. COMMISSION_TOTAL_ANNUALISED ) COMMISSION_TOTAL_ANNUALISED, sum(a1.TERRORISM_GST_ANNUALISED ) TERRORISM_GST_ANNUALISED
, sum(a1.TERRORISM_RI_ANNUALISED ) TERRORISM_RI_ANNUALISED, sum(a1.STAMP_DUTY_ANNUALISED ) STAMP_DUTY_ANNUALISED
, sum(a1.GST_ANNUALISED ) GST_ANNUALISED, sum(a1.FSL_ANNUALISED ) FSL_ANNUALISED
, sum(a1.MODIFIED_PREMIUM_ANNUALISED ) MODIFIED_PREMIUM_ANNUALISED
, sum(a1.TECHNICAL_PREMIUM_ANNUALISED ) TECHNICAL_PREMIUM_ANNUALISED
, sum(a1.BASE_PREMIUM_ANNUALISED) BASE_PREMIUM_ANNUALISED
FROM COVER_PREMIUM_MODEL CPM,
COVER_PREMIUM_MODEL CPM_CHILD,
ChildPremiumCTE a1
WHERE
CPM.PREMIUM_LEVEL_CODE = 'PREMRLUP'
AND CPM_CHILD.PARENT_ID = CPM.COVER_PREMIUM_MODEL_ID
AND CPM_CHILD.COVER_PREMIUM_MODEL_REF = a1.COVER_PREMIUM_MODEL_REF
GROUP BY
a1.POLICY_ID,
a1.ADDRESS_ID,
CPM_CHILD.PARENT_ID,
CPM.NAME,
CPM.PREMIUM_LEVEL_CODE,
a1.SUB_PRODUCT_REF,
CPM.COVER_PREMIUM_MODEL_REF,
a1.STATUS_CODE
UNION ALL
select * from ChildPremiumCTE) CoverPremium where CoverPremium.POLICY_ID = 77780029
到目前为止,我已经改进了,
答案 0 :(得分:2)
第一个建议与@LukStorms相同,也总是使用表的别名并在列中添加前缀,以便于理解和调试。
我可以在内部查询中使用Case和WHEN吗?
一切都有成本。在这种情况下,成本似乎可以忽略不计。
对于以下查询,我们将不胜感激。我不是 要求给出最终的优化查询,但要求具体建议 到下面的查询。
GROUP BY
总是一个坏主意。首先使用CTE或#Temp表
仅使用“ require”表和“ Group on on Key”列来编写Group By查询。假设您还需要其他一些列,该列也不属于聚合或分组依据,那么请不要在此处尝试使用该列。 在主查询中联接同一表,以获取不属于聚合的那些列。
然后在Main查询中再次将该CTE或temp表与其他表联接。
这是设计查询的方式。
PREMIUM_MODEL_PART_REF and TRANSACTION_AMOUNT belong to which table ?
表COVER_PREMIUM_MODEL
在查询中使用了3次。将COVER_PREMIUM_MODEL
的需求数据放在#temp table
上。这三个联接必须有一些共同的结果。
节选
select * from (Select * blah blah
UNION ALL
select * from ChildPremiumCTE) a2 where a2.POLICY_ID = 77780029
为什么最后使用where POLICY_ID = 77780029
?
这样,首先将在内部查询中处理大量行,然后最终减少到POLICY_ID = 77780029
。
所以为什么不首先在内部查询中使用POLICY_ID = 77780029
。
内置MAX,SUM之类的函数来喜欢字符串文字
这取决于UDF
的类型以及您所写的内容。
简而言之,UDF
在大多数情况下都是糟糕的表现。
似乎不是MAX, SUM
需要UDF
。