Reputation: 629
I have two records in the table:
STORE VARCHAR2_1
30816 26.399883
30074 29.58.20.9
SELECT *
FROM mig_test sce
WHERE VARCHAR2_1 > 90
AND VARCHAR2_1 not LIKE '%.%.%';
I am querying: "invalid number". Even when I have excluded the faulty record in the where clause
Upvotes: 0
Views: 85
Reputation: 9083
I would approach it with a sub query and with regexp_count to eliminate the data with more than one full stop '.'
:
select *
from (SELECT REGEXP_COUNT(sce.VARCHAR2_1, '[.]') cnt
, sce.store
, VARCHAR2_1
FROM mig_test sce)
where cnt = 1
and CAST(VARCHAR2_1 as number) > 90;
Upvotes: 1
Reputation: 1269443
SQL is free to rearrange computations however it likes. So, that makes your comparison troublesome, because the the value may not be a number.
However, case
does guarantee the order of evaluation of expressions, so you can try:
SELECT *
FROM mig_test sce
WHERE (CASE WHEN VARCHAR2_1 NOT LIKE '%.%.%'
THEN CAST(VARCHAR2_1 as number)
END) > 90
Note that I added in an explicit cast()
.
Alternatively, you can use regular expressions:
WHERE REGEXP_LIKE(VARCHAR2_1, '^(9|[1-9][0-9])[0-9]+[.]?[0-9]*$')
That is, it starts either with 9# or ### and is followed by digits and at most one decimal point.
Upvotes: 2
Reputation: 142720
It is not the second condition that raises the error, but the first one:
SQL> SELECT *
2 FROM mig_test sce
3 WHERE VARCHAR2_1 > 90 --> this
4 AND VARCHAR2_1 not LIKE '%.%.%';
WHERE VARCHAR2_1 > 90
*
ERROR at line 3:
ORA-01722: invalid number
As the column is VARCHAR2
, enclose 90
into single quotes:
SQL> SELECT *
2 FROM mig_test sce
3 WHERE VARCHAR2_1 > '90'
4 AND VARCHAR2_1 not LIKE '%.%.%';
no rows selected
SQL>
See whether CAST helps.
with valid_values as
(select store,
cast (varchar2_1 as number) varc --> cast to number
from mig_test
where regexp_count(varchar2_1, '\.') <= 1 --> remove invalid rows
)
select *
From valid_values
where varc > 90;
db fiddle is here and looks like this:
Cast as number
Upvotes: 2