Sql Oracle视图-求和到变量

Sql Oracle视图-求和到变量,sql,oracle,group-by,Sql,Oracle,Group By,如何缩短以下select语句 create or replace view V_AMV_PLG_QUOTES_50_MS as select sum(NVL(ASK_SIZE,0)) as ASK_VOLUME, CASE WHEN sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END)=0 THE

如何缩短以下select语句

create or replace view V_AMV_PLG_QUOTES_50_MS as 
select 
    sum(NVL(ASK_SIZE,0))    as ASK_VOLUME, 

CASE WHEN 
          sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END)=0 THEN 1 
     ELSE sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END) END     as ASK_PRICE,


    EXCHANGE_SK         as EXCHANGE_SK, 
    PRODUCT_SK          as PRODUCT_SK, 
    BUSINESS_DATE       as BUSINESS_DATE 
from 
    S_AMV_PLG_QUOTE_AGG quotes 
where NVL(BASE_CURR_ASK_PRICE ,0) > 0
group by 
    EXCHANGE_SK, 
    PRODUCT_SK, 
    BUSINESS_DATE 

请注意,很长的计算将显示两次。。我能以某种方式将其插入变量吗?对变量使用CASE操作符?(注意这里有一个求和函数。)

您不能在视图中使用创建和使用变量。如果您只是想避免重复嵌套的case语句,可以将其(和NVL)移动到内嵌视图中:

select 
    sum(MY_ASK_SIZE)    as ASK_VOLUME, 
    CASE WHEN sum(MY_ASK_PRICE)=0 THEN 1 
        ELSE sum(MY_ASK_PRICE)
        END             as ASK_PRICE,
    EXCHANGE_SK         as EXCHANGE_SK, 
    PRODUCT_SK          as PRODUCT_SK, 
    BUSINESS_DATE       as BUSINESS_DATE 
from (
    select
        EXCHANGE_SK, PRODUCT_SK, BUSINESS_DATE,
        NVL(ASK_SIZE,0) as MY_ASK_SIZE,
        CASE WHEN NVL(ASK_SIZE,0)=0 THEN
                CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END
            ELSE ASK_SIZE
            END AS MY_ASK_PRICE
    from  S_AMV_PLG_QUOTE_AGG quotes 
    where NVL(BASE_CURR_ASK_PRICE ,0) > 0
)
group by 
    EXCHANGE_SK, 
    PRODUCT_SK, 
    BUSINESS_DATE;
NVL和case执行一次,分别别名为MY_ASK_SIZE和MY_ASK_PRICE;然后在外部查询中使用这些别名,包括在总和中

如果要避免重复求和,请将其与group by子句一起移动到内嵌视图中:

select 
    ASK_VOLUME          as ASK_VOLUME, 
    CASE WHEN ASK_PRICE=0 THEN 1
        ELSE ASK_PRICE
        END             as ASK_PRICE,
    EXCHANGE_SK         as EXCHANGE_SK, 
    PRODUCT_SK          as PRODUCT_SK, 
    BUSINESS_DATE       as BUSINESS_DATE 
from (
    select
        EXCHANGE_SK, PRODUCT_SK, BUSINESS_DATE,
        SUM(NVL(ASK_SIZE,0)) as ASK_VOLUME,
        SUM(CASE WHEN NVL(ASK_SIZE,0)=0 THEN
                CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END
            ELSE ASK_SIZE
            END) AS ASK_PRICE
    from  S_AMV_PLG_QUOTE_AGG quotes 
    where NVL(BASE_CURR_ASK_PRICE ,0) > 0
    group by 
        EXCHANGE_SK, 
        PRODUCT_SK, 
        BUSINESS_DATE
);
大多数列别名都是多余的,但我坚持使用您的模式


不过,这在很大程度上是装腔作势;Oracle的Optimizer可能足够聪明,无论如何只执行一次实际计算,因此我不希望看到太多(或任何)性能差异。

我使用了创建一个简单的ifZeroReturnOne函数:

CREATE OR REPLACE FUNCTION ifZeroReturnOne (expr IN NUMBER)
RETURN NUMBER
IS retval NUMBER;
BEGIN
SELECT CASE WHEN expr=0 THEN 1
ELSE expr END
INTO retval
FROM DUAL;
RETURN (retval);
END;
而不是我在查询中使用的:

select sum(NVL(ASK_SIZE,0))    as ASK_VOLUME, 

ifZeroReturnOne (sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END)    as ASK_PRICE,


EXCHANGE_SK         as EXCHANGE_SK, 
etc...............

如果您有更好的建议,请告诉我

注意,我想对所有这些冗长的东西求和,如果和等于0,我想使用1,否则使用和的结果..您应该能够对这种逻辑使用解码。您担心性能或代码维护还是什么?代码维护。。看起来很奇怪,原来的sum查询要长得多,我删除了大部分内容…注意sum(NVL(ASK\u SIZE,0))更好地表示为Coalesce(sum(ASK\u SIZE),0)并且,“NVL(BASE\u CURR\u ASK\u PRICE,0)>0”与“BASE\u CURR\u ASK\u PRICE>0”相同