Phân Biệt NOT IN Và NOT EXISTS Trong SQLServer - Nắng Thủy Tinh

Trong khi học CSDL, chắc hẳn có nhiều bạn sẽ thắc mắc về việc sử dụng NOT IN hay NOT EXISTS, IN hay EXISTS. Để giải thích điều trên tôi sẽ sử dụng sơ đồ CSDL sau để minh họa. Lược đồ CSDL:

KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, DOANHSO, NGDK) NHANVIEN (MANV,HOTEN, NGVL, SODT) SANPHAM (MASP,TENSP, DVT, NUOCSX, GIA) HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) CTHD (SOHD,MASP,SL)

Diagram: diagram.jpg

Câu hỏi minh họa:

Tìm những sản phẩm của Singapore mà SoHD ‘1001’ chưa mua.

Khi phân tích ta có thể thấy đây là câu hỏi sử dụng phép trừ  để thực hiện. Cụ thể: Những Sản phẩm của Singapore mà SoHD ‘1001’ chưa mua = Tất cả Sản phẩm của Singapore –  (Những Sản phẩm của Singapore mà SoHD ‘1001’ đã mua) Trong SQL ta có thể sử dụng NOT IN hoặc NOT EXISTS để thực hiện phép trừ này.

+ Sử dụng NOT IN

  1. SELECT *
  2. FROM SANPHAM
  3. WHERE NUOCSX='SINGAPORE' AND MASP NOT IN(--Câu truy vấn con
  4.                     SELECT MASP
  5.                     FROM CTHD
  6.                     WHERE SOHD='1001')

Câu truy vấn con sẽ trả về giá trị của MASP thõa mãn điều kiện SOHD=’1001′ và các giá trị này xem như là một mảng. Câu truy vấn cha khi sử dụng  NOT IN sẽ duyệt qua từng phần tử của mảng và so sánh để chọn những MASP nào không nằm trong mảng trên.

+ Sử dụng NOT EXISTS

  1. SELECT *
  2. FROM SANPHAM A
  3. WHERE NUOCSX='SINGAPORE' AND NOT EXISTS(--Câu truy vấn con
  4.                     SELECT *
  5.                     FROM CTHD B
  6.                     WHERE SOHD='1001' AND A.MASP=B.MASP)

Câu truy vấn con sẽ chọn ra những bộ thõa mãn điều kiện SOHD=’1001′ và có MASP nằm trong 2 bảng CTHD và SANPHAM.

Điều đáng chú ý ở đây là NOT EXIST chỉ trả về giá trị True hoặc False   + Giá trị của NOT EXIST chỉ đúng khi câu truy vấn con không trả về bộ giá trị nào (Lý thuyết) + Và ngược lại giá trị của NOT EXIST sai khi có  các bộ giá trị trả về. Ở ví dụ này: + Nếu câu truy vấn con không trả về bộ giá trị nào có nghĩa là SOHD ‘1001’ CHƯA MUA BẤT KỲ SẢN PHẨM NÀO => ĐIỀU KIÊN NOT EXISTS ĐÚNG => CÂU TRUY VẤN CHÍNH TRẢ VỀ TẤT CẢ NHỮNG BỘ SẢN PHẨM DO SINGAPORE SẢN XUẤT(NHỮNG SP NÀY CHÍNH LÀ NHỮNG SP MÀ SOHD ‘1001’ CHƯA MUA ) => Thõa yêu cầu câu hỏi đặt ra.

Nhận xét: – Khi sử dụng NOT IN, câu truy vấn cha sẽ duyệt qua rất nhiều lần để đưa ra những bộ giá trị thõa mãn. NOT IN sẽ tìm ra tất cả các bộ thõa yêu cầu câu truy vấn con rồi mới so sánh với câu truy vấn mẹ – Với NOT EXISTS câu truy vấn cha xem NOT EXIST như một điều kiện, thực hiện truy vấn nếu NOT EXIST đúng và ngược lại. NOT EXISTS  sẽ quét từng bộ ở câu truy vấn con và so sánh trực tiếp với yêu cầu của mẹ, nếu không thõa là loại trừ ngay Đây có thể xem như là khác biệt quan trọng nhất giữa NOT IN và NOT EXISTS Sử dụng NOT EXISTS có vẻ “phức tạp”, khó hiểu hơn nhưng thực ra Sever thực hiện câu truy vấn dễ dàng hơn.

Vậy nếu: Câu truy vấn con quét ở một quan hệ có số bộ từ ít đến trung bình hoặc biết trước số lượng bộ cần quét thì nên dùng IN VÀ NOT IN sẽ ngược lại nếu câu truy vấn con đòi hỏi phải quét nhiều quan hệ có sốbộ lớn và không xác định trước số lượng bộ thì nên dùng EXISTS và NOT EXITST lại tốt hơn

NHƯ VẬY, vấn đề: Tìm những sản phẩm của Singapore mà SoHD ‘1001’ chưa mua. đã giải quyết xong!

PHÉP CHIA: Ứng với ví dụ trên, tôi muốn minh họa luôn phép chia để các bạn được nắm, vì sao ta có thể gọi Phép chia là lồng của hai phép trừ.

Ví dụ cần truy vấn: Tìm số hóa đơn đã mua tất cả sản phẩm do Singapore sản xuất Trước khi giải đáp câu hỏi minh họa, chúng ta cùng đã làm câu hỏi PHỤ ở trên là Tìm những sản phẩm của Singapore mà SoHD ‘1001’ chưa mua vì sao có thể dễ dàng tìm những sản phâm của Singapore mà một SoHD BẤT KỲ chưa mua.

Theo lý thuyết đại số quan hệ, để giải quyết câu hỏi này, ta sử dụng phép chia. R1  <–  CTHD[SOHD,MASP] R2 <–  SANPHAM: NUOCSX=’SINGAPORE’ R3 <– R2[MASP] R4 <–  R1:R3

Và bạn có nhận thấy được mối quan hệ giữa câu hỏi chính và câu hỏi phụ của chúng ta không?

Câu hỏi phụ yêu cầu chúng ta tìm những sản phẩm của Singapore mà một Số hóa đơn bất kỳ chưa mua, để đơn giản như ở trên mình đã chỉ định số hóa đơn là 1001. Vậy nếu giá trị của câu hỏi phụ trả về là không có sản phẩm nào thì có nghĩa là Số hóa đơn đó đã mua tất cả sản phẩm của Singapore. Ta lại liên tưởng tới một câu truy vấn sử dụng NOT EXISTS, và bây giờ câu hỏi phụ chính là điều kiện NOT EXIST của câu hỏi chính.

  1. SELECT DISTINCT SOHD FROM CTHD A
  2.  WHERE NOT EXISTS(--câu hỏi phụ
  3.         SELECT * FROM SANPHAM B
  4.         WHERE NUOCSX='SINGAPORE' AND NOT EXISTS(
  5.                 SELECT * FROM CTHD C
  6.                 WHERE C.MASP=B.MASP AND C.SOHD=A.SOHD)
  7.                 )

Đến đây bạn đã rút ra được gì về mối quan hệ của phép trừ và phép chia chưa nhỉ? Rõ ràng trực quan bạn có thể thấy rằng, phép trừ chính là “con” của phép chia.  Hay nói cách khác, khi bạn thực hiện phép chia là bạn đã đồng thời lồng 2 phép trừ vào trong đó. 

Vậy ta có thể sử dụng 2 NOT IN lồng vào nhau để thực hiện phép trừ hay không? Đó là câu hỏi mới xuất hiện trong đầu của mình. Có lẽ chúng ta sẽ phát hiện được nhiều hơn, đúng, hoặc sai, chúng ta sẽ tự đặt ra nhiều câu hỏi hơn khi chúng ta cùng thảo luận và suy nghĩ về nó.

Các nguồn tham khảo:

https://trongthaonh.wordpress.com/2011/11/06/not-in-and-not-exists-in-sql/

https://groups.google.com/forum/#!topic/isteam-test-2011/By5TdoIu1XQ

https://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/

Share this:

  • Twitter
  • Facebook
Like Loading...

Related

Từ khóa » Câu Lệnh Exit Trong Sql