1

这是查询

SELECT * FROM customers  
WHERE 
     NOT EXISTS 
     (     
          SELECT 1 FROM brochure_requests     
          WHERE  brochure_requests.first_name = customers.customer_first_name AND    
          brochure_requests.last_name = customers.customer_last_name
     )

这个查询工作得很好,但我不确定它为什么工作。在 NOT EXISTS 部分中1SELECT 1是什么意思。当我运行此查询时

select 1 from test2

结果如下:

1
-----
1
1
1
1
1
1
1
1
1
1
1
..

不存在查询如何工作?

4

7 回答 7

3

编译器足够聪明,可以忽略SELECT. EXISTS所以,基本上,如果它会因为过滤器匹配而返回行,那就是它所关心的......永远不会执行的SELECT部分。EXISTS它仅将 EXISTS 子句用于评估目的

我有这个误解很长一段时间,因为你会看到SELECT 1很多。但是,我见过 42、* 等......它从不真正关心结果,只是会有一个 :)。要记住的关键是 SQL 是一种编译语言,因此它会适当地优化它。

你可以放一个 1/0 并且它不会抛出被零除的异常......从而进一步证明结果集没有被评估。这显示在这个 SQLFiddle

小提琴的代码:

CREATE TABLE test (i int)
CREATE TABLE test2 (i int)

INSERT INTO test VALUES (1)
INSERT INTO test2 VALUES (1)

SELECT i
FROM test
WHERE EXISTS
(
  SELECT 1/0
  FROM test2
  WHERE test2.i = test.i
)

最后,更重要的是,NOT简单地否定 an EXISTS,说 IGNORE 任何匹配的行

于 2012-04-05T16:14:13.097 回答
1

子查询是所选字段上的和表之间的关联子查询连接。customersbrochure_requests

EXISTS子句只是一个仅返回匹配行(以及NOT否定该行)的谓词。

于 2012-04-05T16:15:21.787 回答
0

查询:

select 1 from test2

显示值 1 作为 test2 表中所有记录的值。

每个SELECT查询必须至少有一列。我认为这就是这里使用值为 1 的未命名列的原因。

子查询为您提供表中相关客户的行brochure_requests

NOT EXISTS导致主查询返回表中所有Customers不在表中的行brochure_requests

于 2012-04-05T16:25:22.763 回答
0

有问题的关系运算符被称为“反连接”(或者“不匹配”或“半差异”)。在自然语言中:使用公共属性 first_name 和 last_name 不匹配 brochure_requests 的客户。

密切相关的运算符是关系差异(或者“减号”或“除外”),例如在 SQL 中

SELECT customer_last_name, customer_first_name
  FROM customers  
EXCEPT
SELECT last_name, first_name  
  FROM brochure_requests;
于 2012-04-10T10:37:21.450 回答
-1

如果客户要求提供小册子,则子查询会为此客户返回 1。并且不会将此客户添加到返回结果集中。bcouse of NOT EXISTS 子句。

于 2012-04-05T16:16:05.170 回答
-1

注意:我不了解 Oracle,也不是特别擅长 SQL。

但是,SELECT 1 from只需为匹配该子句1的每一行返回一个。from因此内部select可以找到brochure_requests名称字段与customer当前正在考虑的行匹配的行,它将产生1结果并失败NOT EXISTS

因此,查询会选择所有姓名customers不匹配的人。brochure_request

于 2012-04-05T16:16:20.593 回答
-2

对于表Customers的每一行,查询在sub-query. NOT EXISTS不返回任何行。

如果中的子查询NOT EXISTS返回行,Customers则不返回表的行。

于 2012-04-05T16:17:06.987 回答