I want to filter on the result of a join, using a cast. The problem is that part of the original field cannot be cast to an Integer. It would not be a problem if the filter was applied after the join. This is why I wonder if there's a way (perhaps an Optimizer Hint or something) to push the filter evaluation after the join operation.
This is a query that I built for the example. I would expect it to work, but fails with an 'ORA-01722 invalid number' :
WITH "literal" AS (
SELECT 1 AS "literal_id", 'abc' AS "literal"
FROM "DUAL"
UNION
SELECT 2 AS "literal_id", '7' AS "literal"
FROM "DUAL"
),
"scalar" AS (
SELECT 3 AS "scalar_id", 2 AS "literal_id"
FROM "DUAL"
CONNECT BY ROWNUM <= 10000
)
SELECT *
FROM "scalar"
JOIN "literal" USING ("literal_id")
WHERE TO_NUMBER("literal") > 6;
The ORA-01722 is thrown because it's applied on the "literal" CTE, hence crashes because 'abc' is obviously not a number. We can see this in the execution plan :
To reduce the possibilities around the cause of my problem, I executed that query:
CREATE TABLE "literal" AS (
SELECT 1 AS "literal_id", 'abc' AS "literal"
FROM "DUAL"
UNION
SELECT 2 AS "literal_id", '7' AS "literal"
FROM "DUAL"
);
CREATE TABLE "scalar" AS (
SELECT 3 AS "scalar_id", 2 AS "literal_id"
FROM "DUAL"
CONNECT BY ROWNUM <= 10000
);
CREATE TABLE "joined" AS (
SELECT *
FROM "scalar"
JOIN "literal" USING ("literal_id")
);
SELECT *
FROM "joined"
WHERE TO_NUMBER("literal") > 6;
Which works perfectly fine.
So, is there a way to rewrite this query (I still need this to be a single query though) so it will not try to convert the 'abc' ?
For reference, I tried this on Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0 as well as Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Thanks a lot.