2017-08-02 55 views
1

這是一個強力的方式來實現,我以後什麼,但有可能是一個更有效的方式提高Oracle查詢的申請每月因素,每月預算的查詢值

SELECT sum(jan/(SELECT JAN FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_JAN, 
     sum(feb/(SELECT FEB FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_FEB, 
     sum(mar/(SELECT MAR FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_MAR, 
     sum(apr/(SELECT APR FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_APR, 
     sum(may/(SELECT MAY FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_MAY, 
     sum(jun/(SELECT JUN FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_JUN, 
     sum(jul/(SELECT JUL FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_JUL, 
     sum(aug/(SELECT AUG FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_AUG, 
     sum(sep/(SELECT SEP FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_SEP, 
     sum(oct/(SELECT OCT FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_OCT, 
     sum(nov/(SELECT NOV FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_NOV, 
     sum(dec/(SELECT DEC FROM MONTHLY_FACTORS WHERE YEAR = '2017')) as FACTORED_DEC, 
     sum( 
       jan/(SELECT JAN FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       feb/(SELECT FEB FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       mar/(SELECT MAR FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       apr/(SELECT APR FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       may/(SELECT MAY FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       jun/(SELECT JUN FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       jul/(SELECT JUL FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       aug/(SELECT AUG FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       sep/(SELECT SEP FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       oct/(SELECT OCT FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       nov/(SELECT NOV FROM MONTHLY_FACTORS WHERE YEAR = '2017') + 
       dec/(SELECT DEC FROM MONTHLY_FACTORS WHERE YEAR = '2017') 
       ) as FACTORED_YEAR_TOTAL 
       FROM MONTHLY_BUDGET 
       WHERE DEPT = '123ABC' AND YEAR = '2017' 

的MONTHLY_FACTORS表看起來像

YEAR JAN FEB ... DEC 
2016 3 2 ... 4 
2017 ... 

的MONTHLY_BUDGET表看起來像

YEAR DEPT JAN  FEB ... DEC 
2016 123abc 50234 20032  22234 
2017 123abc ... 
2016 xyz456 40054 23002 ... 44442 

的預期輸出看起來像

YEAR JAN/JAN_FACTOR  FEB/FEB_FACTOR ... DEC/DEC_FACTOR 

有沒有一個更清潔的方式沒有所有的子查詢?

+1

對於查看預期輸出的示例很有幫助。我在MONTHLY_BUDGET表的示例數據中沒有看到名爲DEPT的列。 – Stilgar

+0

我應該沒有把部門編號弄混了。我應該把它排除在外。 – jeff

+0

表格格式是固定的還是可以更改爲單行上的年份和月份? – Stilgar

回答

0
/* Formatted on 8/2/2017 11:07:39 PM (QP5 v5.287) */ 
WITH a 
    AS ( SELECT year, 
        SUM (jan) jan, 
        SUM (feb) feb, 
        SUM (mar) mar, 
        SUM (apr) apr, 
        SUM (may) may, 
        SUM (jun) jun, 
        SUM (jul) jul, 
        SUM (aug) aug, 
        SUM (sep) sep, 
        SUM (oct) oct, 
        SUM (nov) nov, 
        SUM (dec) dec 
      FROM MONTHLY_BUDGET 
      WHERE DEPT = '123abc' and year= 2017 
     GROUP BY dept, year), 
    b 
    AS (SELECT JAN, 
       FEB, 
       MAR, 
       APR, 
       MAY, 
       JUN, 
       JUL, 
       AUG, 
       SEP, 
       OCT, 
       NOV, 
       DEC, 
       year 
      FROM MONTHLY_FACTORS where year = 2017) 
SELECT a.jan/b.JAN, 
     a.feb/b.FEB, 
     a.mar/b.mar, 
     a.apr/b.apr, 
     a.may/b.may, 
     a.jun/b.jun, 
     a.jul/b.jul, 
     a.aug/b.aug, 
     a.sep/b.sep, 
     a.oct/b.oct, 
     a.nov/b.nov, 
     a.dec/b.dec 
    FROM a, b 
WHERE a.year = b.year 

上述查詢不是一個好的解決方案,但更簡單。

注意:'MONTHLY_BUDGET'中的select *不重要,其中DEPT ='123ABC'AND YEAR ='2017'語句返回一個或多個行。如果您保證返回一行,請勿在'with'子句中使用'sum'。

另一方面,我們可以爲您的情況編寫一個函數。

0

我會開始通過unpivoting的表,所以你有年/月行。意見將爲此工作。如果你可以添加視圖到數據庫,太棒了。如果沒有,您可以將它們轉換爲內聯視圖。

我在1月使用了M01,在2月使用了M02。但是這些只是標籤,你可以使用任何你想要的東西。

CREATE OR REPLACE VIEW tmp_MF 
AS 
WITH 
    MF AS 
     (
     SELECT 
      TO_CHAR(Year)  AS Year 
      ,TO_CHAR(M01)  AS M01 
      ,TO_CHAR(M02)  AS M02 
      ,TO_CHAR(M03)  AS M03 
      ,TO_CHAR(M04)  AS M04 
      ,TO_CHAR(M05)  AS M05 
      ,TO_CHAR(M06)  AS M06 
      ,TO_CHAR(M07)  AS M07 
      ,TO_CHAR(M08)  AS M08 
      ,TO_CHAR(M09)  AS M09 
      ,TO_CHAR(M10)  AS M10 
      ,TO_CHAR(M11)  AS M11 
      ,TO_CHAR(M12)  AS M12 
     FROM tmp_Monthly_Factors    mf 
     ) 
SELECT 
    Year 
    ,"Value" 
    ,"Month" 
FROM mf 
UNPIVOT 
    (
    "Value" 
    FOR "Month" IN (M01,M02,M03,M04,M05,M06,M07,M08,M09,M10,M11,M12) 
    ) 
; 

CREATE OR REPLACE VIEW tmp_MB 
AS 
    WITH 
    MB AS 
     (
     SELECT 
      TO_CHAR(mb.Year)  AS Year 
      ,Dept 
      ,TO_CHAR(M01)  AS M01 
      ,TO_CHAR(M02)  AS M02 
      ,TO_CHAR(M03)  AS M03 
      ,TO_CHAR(M04)  AS M04 
      ,TO_CHAR(M05)  AS M05 
      ,TO_CHAR(M06)  AS M06 
      ,TO_CHAR(M07)  AS M07 
      ,TO_CHAR(M08)  AS M08 
      ,TO_CHAR(M09)  AS M09 
      ,TO_CHAR(M10)  AS M10 
      ,TO_CHAR(M11)  AS M11 
      ,TO_CHAR(M12)  AS M12 
     FROM tmp_Monthly_Budget    mb 
     ) 
SELECT 
    Year 
    ,Dept 
    ,"Month" 
    ,"Value" 
FROM mb 
UNPIVOT 
    (
    "Value" 
    FOR "Month" IN (M01,M02,M03,M04,M05,M06,M07,M08,M09,M10,M11,M12) 
    ) 
; 

然後,我認爲一個PIVOT查詢將得到您想要的結果。這可能需要稍微調整,但應該接近:

WITH 
    Pivot_Data AS 
     (
     SELECT 
      tmp_MB.Year 
      ,tmp_MB.Dept 
      ,tmp_MB."Month" 
    --  ,tmp_MB."Value" AS Budget_Value 
    --  ,tmp_MF."Value" AS Monthly_Factor 
      ,ROUND(tmp_MB."Value"/tmp_MF."Value",2) AS Month_Value 
     FROM tmp_MB 
      -- 
      JOIN tmp_MF 
       ON tmp_MF.Year = tmp_MB.Year 
       AND tmp_MF."Month" = tmp_MB."Month" 
     WHERE (1 = 1) 
    -- AND tmp_MB.Year = 2016 
     ) 
SELECT 
    Year 
    ,Dept 
    ,"Jan" AS "Factored Jan" 
    ,"Feb" 
    ,"Mar" 
    ,"Apr" 
    ,"May" 
    ,"Jun" 
    ,"Jul" 
    ,"Aug" 
    ,"Sep" 
    ,"Oct" 
    ,"Nov" 
    ,"Dec" 
    ,"Jan" + "Feb" + "Mar" + "Apr" + "May" + "Jun" + "Jul" + "Aug" + "Sep" + "Oct" + "Nov" + "Dec" AS "Factored Year Total" 
FROM Pivot_Data 
PIVOT 
    (
    MAX(Month_Value) FOR "Month" IN 
     (
     'M01'  AS "Jan" 
     ,'M02'  AS "Feb" 
     ,'M03'  AS "Mar" 
     ,'M04'  AS "Apr" 
     ,'M05'  AS "May" 
     ,'M06'  AS "Jun" 
     ,'M07'  AS "Jul" 
     ,'M08'  AS "Aug" 
     ,'M09'  AS "Sep" 
     ,'M10'  AS "Oct" 
     ,'M11'  AS "Nov" 
     ,'M12'  AS "Dec" 
     ) 
    ) 
ORDER BY Year, Dept 
;