Problem seems to be in data that isn't "numeric" (why do you keep numbers in VARCHAR2
columns)? For example, it contains '123A56'. What is AVG
of that value?
A simple option is to use REGEXP_LIKE
and perform numeric operations only on "valid" values. For example:
SQL> with test (col) as
2 (select '1234.56' from dual union all -- valid
3 select '131' from dual union all -- valid
4 select 'ABC' from dual union all -- invalid
5 select 'xy.23' from dual union all -- invalid
6 select '.3598' from dual union all -- invalid
7 select '12.34.56'from dual -- invalid
8 )
9 select col,
10 to_number(col, '9999D9999', 'nls_numeric_characters = ''.,''') col_as_num
11 from test
12 where regexp_like(col, '^\d+\.?\d+$');
COL COL_AS_NUM
-------- ----------
1234.56 1234,56
131 131
SQL>
Now you can AVG
such values:
SQL> with test (col) as
2 (select '1234.56' from dual union all -- valid
3 select '131' from dual union all -- valid
4 select 'ABC' from dual union all -- invalid
5 select 'xy.23' from dual union all -- invalid
6 select '.3598' from dual union all -- invalid
7 select '12.34.56'from dual -- invalid
8 )
9 select avg(to_number(col, '9999D9999', 'nls_numeric_characters = ''.,''')) result
10 from test
11 where regexp_like(col, '^\d+\.?\d+$');
RESULT
----------
682,78
SQL>
is_number()
user-defined function in a WHERE clause so your view only selects values which can be converted. (In 12c R2 Oracle provide a built-in VALIDATE_CONVERSATION() which does this.) – APCVALIDATE_CONVERSION
? (And thanks - I'm glad I'm not the only one... :-) – Bob Jarvis - Reinstate Monica