NOT IN AND NOT EXISTS IN SQL - My Blog – My Favourite

Để tham gia thảo luận câu hỏi của thầy, mình viết bài này để học hỏi thêm kiến thức… Nội dung câu hỏi:

Các bạn có thể nêu ra sự khác nhau của 2 toán tử trên không. Lúc nào thì nên dùng NOT IN và lúc nào nên dùng NOT EXISTS. Các bạn thử tìm mối liên quan giữa phép trừ và phép chia trong đại số quan hệ và 2 toán tử trên nhé! 

Mình 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:

 Câu hỏi minh họa: 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Ụ sau: – 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

SELECT * FROM SANPHAM WHERE NUOCSX='SINGAPORE' AND MASP NOT IN(--Câu truy vấn con SELECT MASP FROM CTHD 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

SELECT * FROM SANPHAM A WHERE NUOCSX='SINGAPORE' AND NOT EXISTS(--Câu truy vấn con SELECT * FROM CTHD B 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. – 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. Đâ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.

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! Từ đó ta 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.

TRỞ LẠI VỚI CÂU HỎI MINH HỌA: Tìm số hóa đơn đã mua tất cả sản phẩm do Singapore sản xuất 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.

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

Đế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ó.

Cuối cùng xin cảm ơn các bạn đã đọc bài viết của mình. See you next time!

Share this:

  • Facebook
  • X
Like Loading...

Related

Từ khóa » Toán Tử Exists Trong Sql