2017-08-02 75 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 
;