【问题标题】:Is a combined subquery possible for this scenario?这种情况下是否可以使用组合子查询?
【发布时间】:2015-06-23 21:05:11
【问题描述】:

我目前正在尝试优化这个超长查询。我查看了组合子查询,但在有约束的情况下,我未能在一个查询中获得每个组的计数。

是否可以精简以下查询?

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)

【问题讨论】:

  • 查询试图做什么?
  • 为每一年和每一个季度创建一个包含季度的年度总结。
  • 等等,我在办公室有一个任务。我想到了什么我会在一段时间内评论它

标签: sql oracle optimization subquery


【解决方案1】:

您可以使用 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

【讨论】:

  • 不能把 SUM/CASE 移到主查询吗?
  • @jarlh:您可以将所有内容组合到一个查询中,但是 val_q? 值会被多次使用,然后您需要复制 CASE。恕我直言,如果您保留派生表,代码会更简洁。
  • 我在想一些带有 group by 子句的东西
【解决方案2】:

它看起来像一个 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

【讨论】:

【解决方案3】:

据我了解,你可以直接使用group by query来获取每个季度的总和-

喜欢

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

【讨论】:

  • 出于显示原因,我需要选择每个季度。
  • 对于每个季度,结果中都会有一行。没有帮助吗?
  • 我认为他想要的不是很清楚。但后来答案确实优化了代码。我确实认为 group by 子句也是可能的
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2021-07-10
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    相关资源
    最近更新 更多