Reputation: 501
My goal is to get average of val column in table HISTORY only when average of val columns in MYREF is NULL. Below is my code. Is this correct way to do this? Is there an other efficient way? Because, actual data in HISOTY are massive and I want to sure that the scanning the HISTROY will never occur if MYREF has value.
CREATE TABLE HISTORY (THEDATE VARCHAR(20),VAL NUMBER);
INSERT INTO HISTORY VALUES('20170101', 3);
INSERT INTO HISTORY VALUES('20200923', 4);
CREATE TABLE MYREF (VAL NUMBER);
INSERT INTO MYREF VALUES( NULL);
WITH MYREF_VAL AS( SELECT AVG(VAL) FROM MYREF)
,HISTORY_CAL AS (SELECT AVG(VAL) FROM HISTORY)
SELECT NVL((SELECT AVG(VAL) FROM MYREF), (SELECT AVG(VAL) FROM HISTORY)) VAL FROM DUAL
--Expected result 3.5 which is correct
Upvotes: 0
Views: 42
Reputation: 8655
Just use coalesce instead, because Oracle uses short-circuit evaluation
for coalesce
: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions023.htm
WITH MYREF_VAL AS( SELECT AVG(VAL) FROM MYREF)
,HISTORY_CAL AS (SELECT AVG(VAL) FROM HISTORY)
SELECT
COALESCE((SELECT AVG(VAL) FROM MYREF), (SELECT AVG(VAL) FROM HISTORY)) VAL
FROM DUAL;
Simple example:
SQL> select nvl(1, 1/0) a from dual;
select nvl(1, 1/0) a from dual
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
SQL> select coalesce(1, 1/0) a from dual;
A
----------
1
Upvotes: 2