2016-10-13 2 views
0

Я использую подзапрос для операции соединения. Когда я жестко программирую параметры, все работает нормально. Но эти параметры должны поступать из внешнего sql, который, как мне кажется, называется коррелированным запросом. Я хотел бы передать их с использованием псевдонимов таблицы, но это приводит к invalid identifier.Как использовать псевдонимы в объединенном подзапросе Oracle?

Пример изобрел с целью вопроса:

SELECT 
    PR.PROVINCE_NAME 
    ,CO.COUNTRY_NAME 
FROM 
    PROVINCE PR 
    JOIN (
     SELECT COUNTRY_ID, COUNTRY_NAME 
     FROM COUNTRY 
     WHERE COUNTRY_ID=PR.COUNTRY_ID 
    ) CO ON CO.COUNTRY_ID=PR.COUNTRY_ID 
WHERE 
    PR.PROVINCE_ID IN (1,2) 

Это напечатано в, так что я надеюсь, что я не представил каких-либо проблем синтаксиса здесь. Вопрос в частности о COUNTRY_ID=PR.COUNTRY_ID в соответствии с пунктом WHERE. Являются ли псевдонимы законными в таких подзапросах?

+0

Ну, как только я заменяю 'WHERE COUNTRY_ID = PR.COUNTRY_ID' с' WHERE COUNTRY_ID = 123', все работает нормально. Может ли это иметь какое-то отношение к выполнению этого запроса через Oracle SQL Developer версии 3.2.09? – user6651485

ответ

0

Вы используете псевдоним в двух разных местах. С одной стороны он является законным, для другого это не так:

SELECT pr.province_name, co.country_name 
FROM province pr 
    JOIN (
    SELECT country_id, country_name 
    FROM country 
    WHERE country_id = pr.country_id --<< this reference to the outer table/alias is invalid 
) co ON co.country_id = pr.country_id -- this is valid 
WHERE pr.province_id IN (1,2) 

С (стандартом) присоединиться к производной таблице, то внутреннего выбрать не может получить доступ псевдонима или таблицы от внешнего выбора. «Недопустимый идентификатор», который вы получаете, является причиной по строке WHERE country_id = pr.country_id.

Учитывая ваше состояние JOIN, вы можете безопасно удалить это, не изменяя результат. Оптимизатор Oracle достаточно умен, чтобы перетащить это условие в производную таблицу.

В самом деле оптимизатор будет переписать запрос на:

SELECT pr.province_name, co.country_name 
FROM province pr 
    JOIN country co ON co.country_id = pr.country_id 
WHERE pr.province_id IN (1,2); 

Существует, однако, способ доступа к таблице (или псевдонимы) из внешнего запроса в производной таблице: это называется боковое присоединиться.

Это является частью стандарта SQL, но вам необходимо Oracle 12 для того, чтобы иметь возможность использовать его:

Следующая является правовая:

SELECT pr.province_name,co.country_name 
FROM province pr 
    JOIN LATERAL (
     SELECT country_id, country_name 
     FROM country 
     WHERE country_id = pr.country_id 
    ) co ON co.country_id = pr.country_id 
WHERE pr.province_id IN (1,2)
+0

ОК. Так что это просто. Я использую ver 11.2, который не принимает LATERAL. Кроме того, я придумал свой пример с целью вопроса и не могу переписать мой запрос, как вы предложили. Причина в том, что я получаю несколько строк в этом соединении, и suquery поможет мне свести к одной строке, которая мне нужна. Спасибо за быстрый ответ. – user6651485

Смежные вопросы