Вложенный SQL-запрос, ссылающийся на столбец «бабушка и дедушка» - PullRequest
9 голосов
/ 09 марта 2011

У меня особенно сложный запрос для отчета. Он выбирает несколько столбцов из представления и должен создать столбец путем совокупной конкатенации нескольких полей. Чтобы усложнить ситуацию, конкатенация должна содержать 3 поля, даже если в действительности их 0 (конкатенация разделена запятыми, поэтому пустые поля все равно будут замечены).

Мы используем Oracle 11.1.0.7.0.

Чтобы обеспечить обратную совместимость (не обязательно), мы использовали функцию xmlagg для выполнения конкатенации, я полагаю, это было с Oracle 8 или 9.

Этот пример будет упрощен, но я считаю, что он предоставляет достаточно информации. Другими словами, пожалуйста, не сосредотачивайтесь на нормализации структуры таблицы, это строго пример.

person_view
-----------
name
phone
address
position_id


position_table
--------------
position_id
position_title

Итак, запрос, который у нас сейчас есть, и я признаю, что не являюсь гуру SQL, выглядит примерно так:

select
  name,
  phone,
  address,
  (select
     xmlagg(xmlelement(e, position_title || ',')).extract('//text()')
   from
     (select
        position_title
      from
        position_table
      where
        position_table.position_id = person_view.position_id and 
        rownum <= 3
      union all select '' from dual
      union all select '' from dual
      union all select '' from dual
     )
   where
     rownum <= 3
  )
from
  person_view

Моя настоящая ошибка в том, что, похоже, подзапрос, который обеспечивает как минимум 3 строки ввода, не может ссылаться на запрос дедушки и бабушки для определения person_view.position_id.

Я получаю ORA-00904: «PERSON_VIEW». «POSITION_ID»: неверный идентификатор

Производительность не является большой проблемой, так как это отчет, который не будет регулярно запускаться, но мне нужно найти решение для объединения этих данных с абсолютными 3 столбцами данных. Будем весьма благодарны за любые рекомендации, которые помогут переписать запрос или разрешить подзапросу обращаться к соответствующему столбцу дедушки.

1 Ответ

3 голосов
/ 09 марта 2011

Это ограничение в Oracle SQL: вы не можете ссылаться на родительский элемент запроса из подзапроса глубиной более 1 уровня.

Я бы использовал функцию в таком случае:

CREATE OR REPLACE FUNCTION get_title(p_position_id NUMBER) RETURN VARCHAR2 IS
   l_result       LONG;
   l_position_num NUMBER := 0;
BEGIN
   FOR cc IN (SELECT position_title
                FROM position_table
               WHERE position_table.position_id = p_position_id
                 AND rownum <= 3) LOOP
      l_result       := cc.position_title || ',';
      l_position_num := l_position_num + 1;
   END LOOP;
   RETURN l_result || rpad(',', 3 - l_position_num, ',');
END;

Ваш запрос будет выглядеть так:

select
  name,
  phone,
  address,
  get_title(p.position_id) title
from person_view p
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...