1. 程式人生 > >Oracle的一條sql使用臨時表進行查詢

Oracle的一條sql使用臨時表進行查詢

with CTE as(
  SELECT 
    C.SUB_CORP_NAME
    ,B.BUS_PATH_NAME
  	,ROUND(S.ACTUAL_DAY_RUN_TOTAL_MILE / 1000, 2) AS MILE_ALREADY
  	,ROUND(S.DAY_ALREADY_RUN_TOTAL_MILE / 1000, 2) AS CURRENT_MILE
  	,DECODE(S.DAY_ALREADY_RUN_TOTAL_MILE, 0, 0, ROUND(S.ACTUAL_DAY_RUN_TOTAL_MILE / S.DAY_ALREADY_RUN_TOTAL_MILE * 100 ,2)) as RATE
  ,rank() over (order by DECODE(S.DAY_ALREADY_RUN_TOTAL_MILE, 0, 0, ROUND(S.ACTUAL_DAY_RUN_TOTAL_MILE / S.DAY_ALREADY_RUN_TOTAL_MILE * 100 ,2))) rn
  FROM NBBUSITS.T_BUS_PATH_STA_DATA S,NBBUSITS.T_BUS_PATH  B,NBBUSITS.T_BUS_PATH_COMPANY C 
  WHERE 1=1
    AND UPDATE_TIME > to_date(to_char(sysdate,'yyyy/mm/dd'),'yyyy/mm/dd') 
    AND S.BUS_PATH_ID = B.BUS_PATH_ID 
    AND B.BUS_PATH_NAME = C.BUS_PATH_NAME 
    and C.SUB_CORP_NAME like '永平%'
    and S.ACTUAL_DAY_RUN_TOTAL_MILE > 0 and S.DAY_ALREADY_RUN_TOTAL_MILE > 0
)
select b.* from CTE a
left join(
  SELECT 
    T.BUS_PATH_NAME AS CATEGORY
    ,DECODE(SERIES,'CURRENT_MILE','計劃','MILE_ALREADY','實際','RATE','完成率') AS SERIES
    ,value
  from CTE UNPIVOT(value for SERIES in (MILE_ALREADY, CURRENT_MILE, RATE)) T 
  LEFT JOIN NBBUSITS.T_ON_DUTY_INFO D ON T.BUS_PATH_NAME = D.SUB_CORP_NAME
)B
on a.BUS_PATH_NAME = B.category
WHERE 1=1
	and RN <= 10
order by rn,CATEGORY,SERIES

使用到第一個知識點,with xxx as (),將一條sql語句的結果作為一個臨時變數(臨時表)存在xxx,然後在下面就可以將xxx當成表來查詢使用,適用在複雜的又只想用一條sql完事的需求。因本案例需要使用到列轉行,並且需要在結果中以原本的某一列做排序,故用到with xxx as,

另外用到列轉行UNPIVOT、跳躍排序rank() over(order by...)、decode等函式

做為筆記記錄,另拓展瞭解dense_rank() over()、min()/max() over()、lead()/lag() over()、