web-dev-qa-db-ja.com

Oracleサブクエリは、外部ブロック2レベルの変数を表示しません

1つのクエリで投稿と、その投稿に関連付けられた最初のコメントを取得したいと思います。 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:無効な識別子が表示されます。

1つの副選択で正常に機能するようですが、rownumを使用する必要があるため(Oracleでは制限/オフセットなし)、1つだけではコメントを取得できません。

ここで何が悪いのですか?

26
user248789

いいえ、Oracleは、ネストされたサブクエリを1レベル以上深く関連付けません(また、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
46
Quassnoi

プラットフォームに依存しない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、created_date)がコメントの主キーであると想定しています。そうでない場合は、同じcreated_dateのコメントを持つ複数の行の投稿を取得します。

また、Quassnoiが提供する分析を使用するソリューションよりも遅くなる可能性があります。

3
Steve Broberg