0

次のクエリを書いた同僚がいます。最初のものは機能し、2番目のものは機能しません。また、サブクエリから集計関数を削除すると、機能します。オラクルオプティマイザは奇妙なことをしています。何かご意見は?11.1.0.6.064ビットに対してSQLDeveloper3.1で実行します。

これは機能します:

SELECT
  a.fd_customer_key
, b.fd_customer_key
, b.counter
FROM FETCH_CUSTOMER a
, (select fd_customer_key, count(*) as counter from fetch_customer_order group by fd_customer_key) b
where a.fd_customer_key = b.fd_customer_key (+)
and b.counter is null

これはしません:

SELECT
a.fd_customer_key
, b.fd_customer_key
, b.counter
FROM FETCH_CUSTOMER a
, (select fd_customer_key, count(*) as counter from fetch_customer_order group by fd_customer_key) b
 where a.fd_customer_key = b.fd_customer_key (+)
 and b.fd_customer_key is null
4

2 に答える 2

2

実際には、あなたが提供した両方のクエリは同じように機能するはずですが、私があなたの必要性をよく理解している場合、あなたは順序のないfd_customer_keyを選択しようとしていますか?

私はあなたの必要性のために次のクエリを提案します、それはより単純でより消費が少ないです:

SELECT a.fd_customer_key
  FROM FETCH_CUSTOMER a
 WHERE NOT EXISTS (SELECT 1
          FROM fetch_customer_order b
         WHERE a.fd_customer_key = b.fd_customer_key)
于 2012-05-21T14:11:04.550 に答える
0

アンチジョインを作成しようとしているようです(にFETCH_CUSTOMER対応する行がない行を検索してFETCH_CUSTOMER_ORDERください)。

Oracleを使用すると、この巧妙なOUTER JOINトリックを使用して反結合を作成する必要はありません。NOT INまたはNOT EXISTS演算子を使用して、オプティマイザに最適な計画を見つけさせることができます。これは同じように効率的で読みやすくなります。

とにかく、私はあなたの発見を再現することはできません、これが私の設定です:

CREATE TABLE a (ID NUMBER PRIMARY KEY);
CREATE TABLE b (a_id NUMBER NOT NULL, DATA VARCHAR2(30));
INSERT INTO a (SELECT object_id FROM all_objects);
INSERT INTO b (SELECT object_id, object_name 
                 FROM all_objects WHERE object_type = 'VIEW');

SELECT a.id, b.a_id, b.cnt
  FROM a, (SELECT a_id, COUNT(*) cnt FROM b GROUP BY a_id) b
 WHERE a.id = b.a_id (+)
   AND b.cnt IS NULL;

SELECT a.id, b.a_id, b.cnt
  FROM a, (SELECT a_id, COUNT(*) cnt FROM b GROUP BY a_id) b
 WHERE a.id = b.a_id (+)
   AND b.a_id IS NULL;

両方のクエリが行を返すことがわかります。あなたのDBバージョンは何ですか?

于 2012-05-21T14:14:04.547 に答える