Oracle 视图 - 求和到变量
Oracle view - sum to variable
如何缩短以下 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;然后在外部查询中使用这些别名,包括总和。
如果您也想避免重复 SUM,请将其连同 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 的优化器可能足够聪明,无论如何只执行一次实际计算,所以我不希望看到太多(或任何)性能差异。
我创建了一个简单的 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...............
如果有更好的建议请告诉我
如何缩短以下 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;然后在外部查询中使用这些别名,包括总和。
如果您也想避免重复 SUM,请将其连同 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 的优化器可能足够聪明,无论如何只执行一次实际计算,所以我不希望看到太多(或任何)性能差异。
我创建了一个简单的 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...............
如果有更好的建议请告诉我