使用Analytical Funtions和Keep子句

时间:2018-02-07 20:44:26

标签: sql oracle

我有一个长期的查询,可以通过正确的功能缩短(我相信)。我们是否可以使用Max Min Keep等现有功能来提高此查询的效率?我的整个查询发布在下面。

例如:我们是否可以删除CTE并使用maxmin这样的分析函数。这也可以使得排名和几个联接更加明显

SQL:

WITH LAST_VALUE_BEFORE_START_DT AS (
      SELECT DISTINCT * FROM(
      SELECT
      P.CL_ID,
      HISTORYID,
      H.MENT_DT,
      H.ROLE AS MAX_ROLE,
      H.PM_ID AS MAX_P_ID,
      DENSE_RANK() OVER (PARTITION BY P.CL_ID ORDER BY H.MENT_DT DESC  )AS RNK
      FROM MANAGER_HISTORY H
      INNER JOIN CP CCP ON H.CLIID = CCP.CLIID 
      INNER JOIN PROGRAM CP ON PROGRAMID = CP.PROGRAMID         
      WHERE 1=1
        AND CP.TYPEID IN (13,200,11001)
        AND H.ROLE = 'RED'
        AND H.MENT_DT < START_DT
        --AND P.CL_ID = 920917
           )LAST_VALUE_BEFORE_START_DT_RNK
           WHERE 1=1
             AND RNK =1
              )  

,MIN_VALUE_BETWEEN_PROGRAM AS (
        SELECT * FROM(
        SELECT DISTINCT
        P.CL_ID,
        HISTORYID,
        TRUNC(H.MENT_DT) AS MENT_DT,
        H.ROLE AS MIN_ROLE,
        H.PM_ID AS MIN_PM_ID,
        DENSE_RANK() OVER (PARTITION BY P.CL_ID ORDER BY H.MENT_DT)AS RNK
        FROM MANAGER_HISTORY H
        INNER JOIN CP CCP ON H.CLIID = CCP.CLIID
        INNER JOIN PROGRAM CP ON PROGRAMID = CP.PROGRAMID 
        WHERE 1=1
        AND CP.TYPEID IN (13,200,11001)
        AND H.ROLE = 'RED'
        AND H.PM_ID IS NOT NULL
        AND TRUNC(H.MENT_DT) BETWEEN TRUNC(START_DT) AND NVL(END_DT,SYSDATE)
        --AND P.CL_ID = 920917
           ) MIN_VALUE_BETWEEN_PROGRAM_RNK 
           WHERE 1=1

             AND RNK =1                                            
                   )                 

SELECT * FROM (
SELECT 
 X.*, 
DENSE_RANK() OVER (PARTITION BY CL_ID ORDER BY FIRST_ASSGN_DT,MENT_DT ) AS RNK
FROM(                                                          
 SELECT DISTINCT
C.CL_ID,
P.CL_ID,
CP.PROGRAM,
START_DT,
END_DT,
H.ROLE,
H.MENT_DT,
H.PM_ID,
LVBS.MAX_ROLE,
LVBS.MAX_P_ID,
MVBP.MIN_ROLE,
MVBP.MIN_PM_ID
,CASE 
 WHEN H.MENT_DT < START_DT AND LVBS.MAX_ROLE = 'RED' AND LVBS.MAX_P_ID IS   NOT NULL THEN TRUNC(START_DT)
 WHEN H.MENT_DT BETWEEN START_DT AND NVL(END_DT,SYSDATE) AND H.ROLE = 'RED' AND H.PM_ID IS NOT NULL 
  THEN MVBP.MENT_DT      
 ELSE NULL --TESTING PURPOSES
 END FIRST_ASSGN_DT

 FROM MANAGER_HISTORY H
 INNER JOIN CP CCP ON H.CLIID = CCP.CLIID
 INNER JOIN CLIENT C ON CCP.CLIID = C.CLIID
 INNER JOIN PROGRAM CP ON PROGRAMID = CP.PROGRAMID
 LEFT JOIN LAST_VALUE_BEFORE_START_DT LVBS ON P.CL_ID = LVBS.CL_ID
 LEFT JOIN MIN_VALUE_BETWEEN_PROGRAM MVBP ON P.CL_ID = MVBP.CL_ID

 WHERE 1=1
  AND CP.TYPEID IN (13,200,11001)

                             )X)Z
 WHERE 1=1
  AND Z.RNK = 1

0 个答案:

没有答案