Я наблюдаю поведение с CTE, которое я не ожидал (и кажется противоречивым). Не совсем уверен, что это правильно ...
По сути, через CTE я фильтрую строки, чтобы избежать конкретной проблемы, а затем использую результат этого CTE для выполнения вычислений, которые могут привести к ошибкам c строки, которые, как я думал, я удалил в своем CTE ...
Возьмем простую таблицу со столбцом varchar, в которой часто есть номер, но не всегда
CREATE TABLE MY_TABLE(ROW_ID INTEGER NOT NULL
, GOOD_ROW BOOLEAN NOT NULL
, SOME_VALUE VARCHAR NOT NULL);
INSERT INTO MY_TABLE(ROW_ID, GOOD_ROW, SOME_VALUE)
VALUES(1, TRUE, '1'), (2, TRUE, '2'), (3, FALSE, 'ABC');
Я также создаю маленькая таблица с просто числами для объединения на
CREATE TABLE NUMBERS(NUMBER_ID INTEGER NOT NULL);
INSERT INTO NUMBERS(NUMBER_ID) VALUES(1), (2), (3);
Соединение этих двух таблиц на SOME_VALUE приводит к ошибке, потому что 'AB C' не является цифрой c, и кажется, что JOIN оценивается ДО Предложение WHERE ( BAD влияние на производительность здесь ...)
SELECT *
FROM MY_TABLE
INNER JOIN NUMBERS ON NUMBERS.NUMBER_ID = TO_NUMBER(SOME_VALUE)
WHERE ROW_ID < 3; --> ERROR
Итак, я пытаюсь отфильтровать мою первую таблицу через CTE, которая возвращает только те строки, для которых SOME_VALUE равно цифре c
WITH ONLY_GOOD_ONES
AS (
SELECT SOME_VALUE
FROM MY_TABLE
WHERE GOOD_ROW = TRUE
)
SELECT *
FROM ONLY_GOOD_ONES;
Теперь я ожидал бы, что смогу использовать результат этого CTE, когда SOME_VALUE будет иметь числовое значение c.
WITH ONLY_GOOD_ONES
AS (
SELECT SOME_VALUE
FROM MY_TABLE
WHERE GOOD_ROW = TRUE
)
SELECT *
FROM ONLY_GOOD_ONES
INNER JOIN NUMBERS ON NUMBERS.NUMBER_ID = TO_NUMBER(SOME_VALUE);
Чудо !!!
Это сработало! Я получаю свои 2 ожидаемые записи. Пока все хорошо ...
Однако, если бы я определил свой CTE немного по-другому (предложение WHERE, которое фильтрует те же записи)
WITH ONLY_GOOD_ONES
AS (
SELECT SOME_VALUE
FROM MY_TABLE
WHERE ROW_ID < 3
)
SELECT *
FROM ONLY_GOOD_ONES;
Этот CTE возвращает точно то же самое, что и раньше
Но если я попытаюсь присоединиться, произойдет сбой!
WITH ONLY_GOOD_ONES
AS (
SELECT *
FROM MY_TABLE
WHERE ROW_ID < 3
)
SELECT *
FROM ONLY_GOOD_ONES
INNER JOIN NUMBERS ON NUMBERS.NUMBER_ID = TO_NUMBER(SOME_VALUE);
Я получаю следующую ошибку ...
SQL Ошибка [100038] [ 22018]: числовое значение c значение 'AB C' не распознано
Есть ли конкретное объяснение тому, что вторая версия CTE ведет себя по-другому ???