2013-02-21 18 views
5

HAVING EVERY句に対するオラクルのサポートの欠如を回避する方法を見つけるのに問題があります。Oracle SQL - すべての回避策がある標準がありますか?

私は、次のスキーマを持つ2つのテーブル、生産や映画、持っている:「pidは」発行者IDを表す整数である場合、「中期」は映画のIDを表す整数である、と監督は

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

を映画監督の名前。

私の目標は、Peter JacksonまたはBen Affleck監督の映画のみを公開している出版社(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はEVERYをHAVINGサポートしていないため、私が得るすべては次のエラーです:

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

ので、役員は出版社によって制作されたすべての映画に適用されなければならない、私は条件がWHERE句に移動できるとは思わない。

このロードブロッキングの周りには方法がありますか? 「標準」とみなされるものは何ですか?また、(そしておそらくもっと重要なのは)オラクルがなぜそれを実践しないことを選んだのですか?

答えて

4

これを試してみてください:

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 

Here is a sqlfiddle demo

+1

!感謝万円。 私たちはここにいるのに、なぜオラクルがどのように実装されていないのか知っていますか?私は回避コードが非常にハッキー/読みにくいように感じます。それは私にとっては非常に否定的な側面です。 – Dan

+1

+1 - OPリクエストを誤解したため、私の答えを削除しました。いい答え! – sgeddes

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 demo

Tその違いは、所望の取締役だけを持つ生産者を探すのではなく、他の取締役と結びついているすべてのプロデューサーを特定し、それを省略することです。

+0

+1ボックスの外の考え方のために!ダウンデータのみが、大きなデータセットで高価になる相関サブクエリです。私の答えを見てください。 – ninesided

+0

+1これははるかに簡単です! –

2

Dan's own answerに基づいて、それはおそらく大規模なデータセット上で非常にうまく機能しないだろうと私は、相関サブクエリを削除しました:

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 Fiddle demo

関連する問題