5

オラクルが HAVING EVERY 句をサポートしていないことを回避する方法を見つけるのに苦労しています。

次のスキーマを持つ、Production と Movie の 2 つのテーブルがあります。

Production (pid, mid)
Movie(mid, director)

ここで、「pid」は出版社 ID を表す整数、「mid」は映画 ID を表す整数、director は映画の監督の名前です。

私の目標は、ピーター・ジャクソンまたはベン・アフレックが監督した映画のみを公開した出版社のリストを (ID で) 取得することです。

これを達成するために、次のクエリを作成しました。

SELECT *
    FROM Production P, Movie M
    WHERE P.mid = M.mid;
    GROUP BY P.pid
    HAVING EVERY ( M.director IN ('Ben Affleck', 'Peter Jackson') );

しかし、Oracle は HAVING EVERY をサポートしていないため、次のエラーしか表示されません。

    HAVING EVERY ( M.director IN ('ben affleck', 'PJ') )
                          *
ERROR at line 5:
ORA-00907: missing right parenthesis

監督は出版社が制作するすべての映画に適用する必要があるため、この条件を WHERE 句に移すことはできないと思います。

この障害を回避する方法はありますか? 「標準」と見なされるものはありますか?また (そしておそらくもっと重要なことに) Oracle が HAVING EVERY を実装しないことを選択したのはなぜですか?

4

5 に答える 5

5

これを試して:

SELECT P.pid
FROM (select distinct Pi.pid, M.Director
      from Production Pi INNER JOIN 
    Movie M ON Pi.mid = M.mid) P
GROUP BY P.pid
HAVING sum(case when P.Director in ('Ben Affleck', 'Peter Jackson') 
           then 1 else 99 end) = 2

これがsqlfiddleのデモです

于 2013-02-21T21:48:28.123 に答える
3

しばらく考えた後、ABCade が思いついたものよりもおそらくもう少し読みやすいものを思いつきました。

select distinct P.pid
    from Production P
    where P.pid not in (
        -- Get publishers that have produced a movie directed by someone else
        select P1.pid
        from Production P1 INNER JOIN Movie M ON P1.mid = M.mid
        where M.director not in ('Ben Affleck', 'Peter Jackson')
    )

SQLFiddle デモ

違いは、目的のディレクターのみを持つプロデューサーを探すのではなく、他のディレクターにリンクされているすべてのプロデューサーを特定してから除外することです。

于 2013-02-21T22:58:51.307 に答える
2

ダン自身の回答に基づいていますが、大規模なデータセットではパフォーマンスが非常に低下する可能性があるため、相関サブクエリを削除しました。

SELECT DISTINCT P.pid
FROM Production P
LEFT JOIN (
    SELECT P1.pid
    FROM Production P1
    INNER JOIN Movie M ON (P1.mid = M.mid)
    WHERE M.director NOT IN ('Ben Affleck', 'Peter Jackson')
) V ON (P.pid = V.pid)
WHERE v.pid IS NULL;

SQL フィドルのデモ

于 2013-02-21T23:07:31.183 に答える