【问题标题】:How to code long group by/case clauses in Oracle?如何在 Oracle 中编写长 group by/case 子句?
【发布时间】:2012-10-28 19:20:40
【问题描述】:

我经常有一些查询要按 case 子句进行分组,例如:

SELECT
    CASE WHEN FIELD IS NULL                     |
    AND (SOMETHING > 100 OR SOMETHINGELSE < 50) |
    AND THATDATE >= add_months(sysdate, -4)     | -> Case
        THEN 0 ELSE 1                           |                                                               
    END AS dim_1,                               |                                                               
    dim_2,
    sum(SOMEFIELD_TOTAL) as measure_1
FROM MY_TABLE
GROUP BY
    CASE WHEN FIELD IS NULL                     | 
    AND (SOMETHING > 100 OR SOMETHINGELSE < 50) | 
    AND THATDATE >= add_months(sysdate, -4)     | -> Same case
        THEN 0 ELSE 1                           |                                                                
    END,                                        |                                                                
    dim_2

有没有办法可以将我为整个案例定义的别名用于group by,例如group by dim_1

找到this explanation,还是想知道有没有出路。

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    我认为您过于担心重复表达。 Oracle 和任何其他 DBMS 都会将该表达式识别为重复项并仅计算一次。如果您只是不想重复它(这只是 剪切和粘贴 琐事提醒您),您可以使用派生表或公用表表达式。

    SELECT 
        dim_1, dim_2, sum(SOMEFIELD_TOTAL) as measure_1
    FROM (
        SELECT
            CASE WHEN FIELD IS NULL                     |
            AND (SOMETHING > 100 OR SOMETHINGELSE < 50) |
            AND THATDATE >= add_months(sysdate, -4)     | -> Case
                THEN 0 ELSE 1                           |                                                               
            END AS dim_1,                               |                                                               
            dim_2,
            SOMEFIELD_TOTAL
        FROM MY_TABLE
    ) AS SQ
    GROUP BY
        dim_1, dim_2
    

    看起来并没有好多少,是吗?

    【讨论】:

    • 嗯,一般来说我会同意你的。我更关心代码,真的。这个例子很简单,但有时我真的有很长的cases 并且在同一个句子中不止一个。尽管正如您所说,这一切都归结为剪切和粘贴,但当代码变长时,它始终是拼写错误和愚蠢错误的地方。无论如何,您输入的语法将来可能会有所帮助。谢谢。
    【解决方案2】:

    您可以使用subquery factoring 也称为named subquerycommon table expression (CTE)(感谢@a_horse_with_no_name)

    WITH t as 
    (
    SELECT
        CASE WHEN FIELD IS NULL                     
        AND (SOMETHING > 100 OR SOMETHINGELSE < 50) 
        AND THATDATE >= add_months(sysdate, -4)     
            THEN 0 ELSE 1 END AS dim_1,         
        dim_2,
        SOMEFIELD_TOTAL as measure_1
    FROM MY_TABLE
    )
    SELECT dim_1, dim_2, sum(SOMEFIELD_TOTAL)
    FROM t
    GROUP BY dim_1, dim_2
    

    这种方法的优点是你可以有很多子查询,而不必像在常规子查询中那样加入它们(内部选择)

    【讨论】:

    • 附带说明:此功能的“官方”名称(根据 ANSI SQL 标准)是“公用表表达式”(或 CTE)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 2012-07-04
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多