0

据我所知,当子查询包含至少一行时,EXISTS 返回 true,而如果子查询不返回任何内容,则 NOT EXIST 返回 true。因此,对于给定的子查询,两者中的任何一个都应该返回 true,对吗?例如: 1) 这会返回一个或多个城市有什么样的商店?

SELECT DISTINCT store_type FROM stores
WHERE EXISTS 
             (SELECT * 
              FROM cities_stores
              WHERE cities_stores.store_type = stores.store_type);

2)这又回到了没有城市有什么样的商店?

SELECT DISTINCT store_type FROM stores
WHERE NOT EXISTS 
             (SELECT * 
              FROM cities_stores
              WHERE cities_stores.store_type = stores.store_type);

那么同一个子查询如何为这两个查询提供输出呢?因为一个使用 EXIST 而另一个使用 NOT EXIST?

我从 http://dev.mysql.com/doc/refman/5.1/en/exists-and-not-exists-subqueries.html中获取了示例

另外 2 NOT EXISTS 在这里有什么帮助?这不是一种OR吗?3)这会返回所有城市都有什么样的商店?

SELECT DISTINCT store_type FROM stores s1
WHERE NOT EXISTS (
            SELECT * FROM cities 
            WHERE NOT EXISTS (
                         SELECT * FROM cities_stores
                         WHERE cities_stores.city = cities.city
                         AND cities_stores.store_type = stores.store_type));
4

4 回答 4

4

子句的典型用法EXISTS()是检查给定行的某些相关行在相关表中的位置:

CREATE TABLE clients
        ( client_id INTEGER NOT NULL PRIMARY KEY
        , client_name varchar
        );
CREATE TABLE products
        ( product_id INTEGER NOT NULL PRIMARY KEY
        , product_name varchar
        );
CREATE TABLE orders
        ( client_id INTEGER NOT NULL REFERENCES clients(client_id)
        , product_id INTEGER NOT NULL REFERENCES products(product_id)
        , quantity INTEGER NOT NULL DEFAULT 1
        , order_date DATE
        , PRIMARY KEY (client_id,product_id)
        );
INSERT INTO clients(client_id, client_name) VALUES (1, 'Alice' ), (2, 'Bob' ), (3, 'Charly' ), (4, 'Diana' );
INSERT INTO products(product_id, product_name) VALUES (1, 'Apple' ), (2, 'Banana' ), (3, 'Citrus' );
INSERT INTO orders(client_id,product_id,order_date) VALUES (1,2, '2013-9-8'),(2,1, '2013-9-11'),(3,2, '2013-10-1');

-- Find clients who ordered something
SELECT * FROM clients cl
WHERE EXISTS (
        SELECT * FROM orders oo
        WHERE oo.client_id = cl.client_id
        )
        ;

-- Find clients who never ordered anything
SELECT * FROM clients cl
WHERE NOT EXISTS (
        SELECT * FROM orders oo
        WHERE oo.client_id = cl.client_id
        )
        ;

-- Find products that were never ordered
SELECT * FROM products pr
WHERE NOT EXISTS (
        SELECT * FROM orders oo
        WHERE oo.product_id = pr.product_id
        )
        ;
于 2013-10-02T14:55:54.807 回答
2

除此之外,NOT EXISTS通过确保您以不否定索引的方式检查列来提高使用时的性能。我认为这适用于更大的数据集,但仍然很高兴知道。Jayachandran 在这里解释得很好:http: //social.msdn.microsoft.com/Forums/sqlserver/en-US/582544fb-beda-46c0-befd-4b28b5c2cdee/select-not-exists-very-slow

于 2013-10-02T14:17:29.893 回答
1

一个非常有用的例子Where not exists是在插入时。如果您希望防止基于某些条件添加重复行,使用它会很有帮助。

例如,在创建参考数据表时,我还必须IDENTITY_INSERT在数据库之间保持 ID 一致。插入新的参考数据时,我这样做:

INSERT INTO ref_table
(ID, ReferenceData)
SELECT 425, 'foo' where not exists (select 1 from ref_table where ID = 425) UNION ALL
SELECT 426, 'bar' where not exists (select 1 from ref_table where ID = 426) UNION ALL
...
SELECT 532, 'biz' where not exists (select 1 from ref_table where ID = 532)

当然,我总是确保我的插入内容是一致的,但为了安全起见,我添加了这个条款。

于 2013-10-02T15:07:04.507 回答
0

首先,您需要在内部查询(连接)中匹配的商店类型,其次您需要在内部查询中没有匹配的商店类型!!!

使用 EXISTS/NOT EXISTS 子句时,您始终连接内部和外部查询,然后您只需选择是否需要匹配或不匹配的结果。

于 2013-10-02T14:05:22.343 回答