使用含有關鍵字exists查找未分配具體部門的員工的所有信息。
本題可以用EXISTS和IN兩種方法:
/* 1. EXISTS */
SELECT *
FROM employees
WHERE NOT EXISTS (SELECT emp_no
FROM dept_emp
WHERE employees.emp_no = dept_emp.emp_no);
/* 2. IN */
SELECT *
FROM employees
WHERE emp_no NOT IN (SELECT emp_no
FROM dept_emp);
1.什麼時候用EXISTS,什麼時候用IN?
主表爲employees,從表爲dept_emp,在主表和從表都對關聯的列emp_no建立索引的前提下:
- 當主表比從表大時,IN查詢的效率較高;
- 當從表比主表大時,EXISTS查詢的效率較高;
原因如下:
- in是先執行子查詢,得到一個結果集,將結果集代入外層謂詞條件執行主查詢,子查詢只需要執行一次
- exists是先從主查詢中取得一條數據,再代入到子查詢中,執行一次子查詢,判斷子查詢是否能返回結果,主查詢有多少條數據,子查詢就要執行多少次。
關於使用Exists( != )不能通過的原因:
Exists的用法:
- exists對外表用loop逐條查詢,每次查詢都會查看exists的條件語句,當 exists裏的條件語句能夠返回記錄行時(無論記錄行是的多少,只要能返回),條件就爲真,返回當前loop到的這條記錄;反之如果exists裏的條 件語句不能返回記錄行,則當前loop到的這條記錄被丟棄,exists的條件就像一個bool條件,當能返回結果集則爲true,不能返回結果集則爲 false。
- 總的來說,如果外表有n條記錄,那麼exists查詢就是將這n條記錄逐條取出,然後判斷n遍exists條件
如果使用:
select * from employees
where exists( select emp_no from dept_emp where dept_emp.emp_no != employees.emp_no)
- 那麼,Exists都會從外表employees裏面逐條比對,如,第一條的emp_no = ‘10001’,那麼
Exists判斷:
select emp_no from dept_emp where dept_emp.emp_no !='10001'
可想而知,一定存在不等於10001的結果集。那麼上面的查詢語句其實也就等效於:
select * from employees