这种情况可以使用组合子查询吗?

时间:2015-04-17 06:35:53

标签: sql oracle optimization subquery

我目前有这个长时间的查询,我正在尝试优化。我查看了子查询的组合,但是在遇到约束的情况下,我无法在一个查询中计算每个组。

是否可以减少以下查询?

SELECT
    val_year,
    spg,
    SUM(val_q1) val_q1,
    SUM(val_q2) val_q2,
    SUM(val_q3) val_q3,
    SUM(val_q4) val_q4,
    SUM(val_q1) + SUM(val_q2) + SUM(val_q3) + SUM(val_q4) val_total
FROM (
    SELECT
        val_year,
        spg,
        count_prods val_q1,
        0 val_q2,
        0 val_q3,
        0 val_q4
    FROM table_report
    WHERE val_quarter = 'Q1'
    UNION ALL
    SELECT
        val_year,
        spg,
        0 val_q1,
        count_prods val_q2,
        0 val_q3,
        0 val_q4
    FROM table_report
    WHERE val_quarter = 'Q2'
    UNION ALL
    SELECT
        val_year,
        spg,
        0 val_q1,
        0 val_q2,
        count_prods val_q3,
        0 val_q4
    FROM table_report
    WHERE val_quarter = 'Q3'
    UNION ALL
    SELECT
        val_year,
        spg,
        0 val_q1,
        0 val_q2,
        0 val_q3,
        count_prods val_q4
    FROM table_report
    WHERE val_quarter = 'Q4'
)

table_report看起来像这样:

table_report:
val_year VARCHAR2(4)
spg VARCHAR2(256)
val_quarter VARCHAR2(2)
count_prods NUMBER(10)

4 个答案:

答案 0 :(得分:4)

您可以使用CASE将单个查询替换为UNION:

SELECT
    val_year,
    spg,
    CASE WHEN val_quarter = 'Q1' THEN count_prods ELSE 0 END val_q1,
    CASE WHEN val_quarter = 'Q2' THEN count_prods ELSE 0 END val_q2,
    CASE WHEN val_quarter = 'Q3' THEN count_prods ELSE 0 END val_q3,
    CASE WHEN val_quarter = 'Q4' THEN count_prods ELSE 0 END val_q4
FROM table_report

答案 1 :(得分:1)

它看起来像一个PIVOT查询,所以你可以在一个

中完成所有操作
SELECT 
val_year, spg, 
coalesce(q1_total, 0) as q1,
coalesce(q2_total, 0) as q2,
coalesce(q3_total, 0) as q3,
coalesce(q4_total, 0) as q4,
coalesce(q1_total, 0) + coalesce(q2_total, 0) + coalesce(q3_total, 0) + coalesce(q4_total, 0) as total
FROM 
(SELECT val_Year, spg, count_prod, val_quarter FROM test) 
PIVOT (SUM(count_prod) as total
FOR (val_Quarter) IN ('Q1' AS q1, 'Q2' AS q2, 'Q3' AS q3, 'Q4' as q4))s ;

请参阅SqlFiddle

答案 2 :(得分:0)

根据我的理解,您可以直接使用逐个查询来获取每个季度的总和 -

喜欢

选择sum(count_prods)mysum,val_quarter作为季度分组;

答案 3 :(得分:0)

我不确定你想要获得什么结果,但也许你可以尝试这样的方法:

SELECT
        val_year,
        spg,
        val_q1,
        val_q2,
        val_q3,
        val_q4,
        val_q1 + val_q2 + val_q3 + val_q4 as val_total
FROM ( 
   SELECT
        val_year,
        spg,
        sum(case when val_quarter = 'Q1' then count_prods else 0 end) as val_q1,
        sum(case when val_quarter = 'Q2' then count_prods else 0 end) as val_q2,
        sum(case when val_quarter = 'Q3' then count_prods else 0 end) as val_q3,
        sum(case when val_quarter = 'Q4' then count_prods else 0 end) as val_q4
    FROM table_report
    GROUP BY val_year, spg
)

这是一个无数据小提琴:http://sqlfiddle.com/#!4/9bf262/20