0

我有一位同事写了以下查询。第一个有效,第二个无效。此外,如果您从子查询中删除聚合函数,它也可以工作。预言机优化器正在做一些奇怪的事情。有什么想法吗?在 SQL Developer 3.1 中针对 11.1.0.6.0 64 位运行。

这有效:

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 INorNOT 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;

您会发现两个查询都返回行。你的数据库版本是什么?

于 2012-05-21T14:14:04.547 回答