2013-10-02 3 views
0

내가 아는 바에 따르면 EXISTS는 하위 쿼리에 최소한 하나의 행이 포함되어 있으면 true를 반환하고, NOT EXIST는 하위 쿼리가 아무 것도 반환하지 않으면 true를 반환합니다. 주어진 하위 쿼리에 대해 두 중 하나가 true를 반환해야합니다. 맞습니까? 예 : 1) 하나 이상의 도시에있는 상점의 종류를 반환합니다.SQL에 NOT EXISTS를 사용하는 경우는?

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를 사용하고 다른 하나는 존재하지 않는다.

나는 또한 방법이 여기에 도움이 EXISTS되지 않습니다 http://dev.mysql.com/doc/refman/5.1/en/exists-and-not-exists-subqueries.html

에서 예제를했다? 이건 일종의 거래 아닌가요? 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

일부'stores' 행은'cities_stores'에서 일치하는 행을 가지고 있기 때문에 다른 행은 없습니까? – wildplasser

+1

'SELECT DISTINCT store_type' 대신'SELECT *'를 사용하면'EXISTS '와'EXITTS '가하는 일에 대해 더 잘 느끼게 될 것입니다. –

+0

'어떻게 같은 하위 쿼리가 두 쿼리에 대한 결과를 출력 할 수 있습니까? '결과가 같아 보이지 않으므로 양쪽 모두에 출력됩니다. 동일하지 않습니다. – DrCopyPaste

답변

3

일반적인 사용은 주어진 행 에 대한 몇 가지 관련 행이 관련 테이블에을 존재하는 확인하는 것입니다 :

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 
     ) 
     ; 
0

먼저 당신이 내부 쿼리 (가입), 두 번째 당신이 내부 쿼리 일치가없는 저장 유형을 원하는에 일치하는이 가게 유형을 원하는!

EXISTS/NOT EXISTS 절을 사용하면 항상 내부 및 외부 쿼리를 조인 할 때 일치하는 결과가 있거나 일치하지 않는 결과를 원하는지 여부 만 선택하면됩니다.

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) 

난 항상 내 삽입이 일치해야합니다 있는지 확인하지만 난 안전 대책이 절을 추가 : 새로운 참조 데이터를 삽입 할 때, 그래서 같은 해.

관련 문제