Подзапрос Oracle не видит переменную из внешнего блока на 2 уровня выше - PullRequest
25 голосов
/ 12 января 2010

Я хотел бы получить в одном запросе сообщение и первый комментарий, связанный с сообщением. Вот как я делаю это в PostgreSQL:

SELECT p.post_id, 
(select * from 
 (select comment_body from comments where post_id = p.post_id 
 order by created_date asc) where rownum=1
) the_first_comment
FROM posts p  

и работает нормально.

Однако в Oracle я получаю ошибку ORA-00904 p.post_id: неверный идентификатор.

Кажется, что это нормально работает для одного подвыбора, но я не могу получить комментарий только с одним из-за того, что мне нужно использовать rownum (без ограничения / смещения в Oracle).

Что я здесь не так делаю?

Ответы [ 2 ]

46 голосов
/ 12 января 2010

Нет, Oracle не коррелирует вложенные запросы, вложенные более чем на один уровень (и не MySQL).

Это известная проблема.

Используйте это:

SELECT  p.post_id, c.*
FROM    posts
JOIN    (
        SELECT  c.*, ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY created_date ASC) AS rn
        FROM    comments c
        ) c
ON      c.post_id = p.post_id
        AND rn = 1
3 голосов
/ 12 января 2010

Если вам нужен SQL, который не зависит от платформы, это будет работать:

SELECT p.post_id
     , c.comment_body
  FROM posts p
     , comments c
 WHERE p.post_id = c.post_id
   AND c.created_date IN
       ( SELECT MIN(c2.created_date)
           FROM comments c2
          WHERE c2.post_id = p.post_id
        );

Но предполагается, что (post_id, creation_date) является первичным ключом комментариев. Если это не так, вы получите несколько постов с комментариями с одной и той же созданной датой.

Кроме того, оно, вероятно, будет медленнее, чем решение, использующее аналитику, предоставленное Quassnoi.

...