1. 程式人生 > >SQL中NOT EXISTS...[EXCEPT]的妙用

SQL中NOT EXISTS...[EXCEPT]的妙用


title: ‘SQL中NOT EXISTS…[EXCEPT]的妙用’
date: 2018-11-13 16:15:30
tags: SQL
categories: 資料庫、SQL
toc: true
這是基於github的個人部落格:Josonlee’s Blog


EXISTS子查詢可以理解為存在,但也不能死扣字眼,多用在where子句中用來刪選滿足條件的記錄,只要子查詢能找到就是True,EXISTS條件就成立,反之不成立;NOT EXISTS與之相反

NOT EXISTS用法

有以下四張表:

Product (pID, name, category, UnitType, sID, price )
Order (oID, year, month, day, type, cID, shipType, status)
OrderDetail (oID, oDetailNum, pID, unitPrice, quantity)
Customer (cID, name, address, phone, creditLimit)
  • 利用not exists 的子查詢思想解決如下查詢
    • 查詢從未在2012年10月賣出去的產品資訊,
    • 具體包括: 商品ID,商品名

not exists就是【沒有、從未】,其後跟隨的子查詢就是要解決的後半段問題【肯定部分】

Select pID, name
From product
Where not exists
    (select *
    From order join orderDetail
        on order.oID = orderDetail.oID
    Where year=2012 and month
=10 and product.pID = orderDetail.pID)

有上面程式碼可以看出not exists只是解釋了需求中的【從未】,而子查詢負責【在2012年10月賣出去的產品資訊】

如果子查詢結果集為空,就是沒有售賣的資訊,not exists【沒有、不存在】滿足,條件成立

NOT EXISTS… EXCEPT 用法

  • 查詢學生,該生通過了其所屬的系開設的 所有 課程,列出stu_name,dept_name
    • 要用到的有student表(包含學生id,所屬的系名,學生名),Course表(包含開課的系名,課程id等),takes表(包含學生id,課程id,成績等)
select name, dept_name
  from student
  where not exists (
      select course_id
      from course
      where student.dept_name=course.dept_name
      except
      select course_id
      from takes
      where student.ID = takes.ID 
          and grade != 'F'
  )

我們知道except是求差集,所以可以有如下解釋

  where not exists (
      該學生所屬的系開設的所有課程C1
      except
      學生所有及格的課程C2
  )

C1-C2為空,就是C1是C2的子集,not exists成立,滿足條件

  • not exists… except 有兩種用法,要根據所求語義判斷

比如說公司中若干部門,若干等級的職位

  • 求所有職位都是B等級的部門
    • {部門所有職位} except {所有B等級的職位}
  • 求包含所有B等級職位的部門
    • {所有B等級的職位} except {部門所有職位}

其實很簡單,判斷時畫個圖,就知道誰該包含誰了

如果還想不通,可以參考這篇分析更細緻的文章:查詢選修了全部課程的學生姓名


這是基於github的個人部落格:Josonlee’s Blog
歡迎前來搭訕