Sql Oracle视图-求和到变量
如何缩短以下select语句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
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”相同