幾個表
employees 表:
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME VARCHAR2(25)
EMAIL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE DATE
JOB_ID VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
jobs 表:
JOB_ID VARCHAR2(10)
JOB_TITLE VARCHAR2(35)
MIN_SALARY NUMBER(6)
MAX_SALARY NUMBER(6)
departments 表:
DEPARTMENT_ID NUMBER(4)
DEPARTMENT_NAME VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)
locations 表:
|
LOCATION_ID |
|
NUMBER(4) |
|
|
STREET_ADDRESS |
VARCHAR2(40) |
||
|
POSTAL_CODE |
VARCHAR2(12) |
||
|
CITY |
VARCHAR2(30) |
||
|
STATE_PROVINCE |
VARCHAR2(25) |
||
|
COUNTRY_ID |
CHAR(2) |
job_grades 表:
GRADE_LEVEL VARCHAR2(3)
LOWEST_SAL NUMBER
HIGHEST_SAL NUMBER
1 一般查詢
1. 查詢每個月倒數第2 天入職的員工的信息.
2. 查詢出last_name 爲 'Chen' 的 manager 的信息.
3. 查詢平均工資高於8000 的部門 id 和它的平均工資.
4. 查詢工資最低的員工信息:last_name, salary
5. 查詢平均工資最低的部門信息
6. 查詢平均工資最低的部門信息和該部門的平均工資
7. 查詢平均工資最高的job 信息
8. 查詢平均工資高於公司平均工資的部門有哪些?
9. 查詢出公司中所有manager 的詳細信息.
10. 各個部門中 最高工資中最低的那個部門的 最低工資是多少
11. 查詢平均工資最高的部門的manager 的詳細信息: last_name,department_id, email, salary
12. 查詢1999 年來公司的人所有員工的最高工資的那個員工的信息.
13. 返回其它部門中比job_id 爲‘IT_PROG’部門所有工資都低的員工的員工號、姓名、job_id 以及salary
************************answers*********************
1.查詢每個月倒數第 2 天入職的員工的信息.
select last_name, hire_date from employees where hire_date = last_day(hire_date) – 1
2. 查詢出 last_name 爲 'Chen' 的 manager 的信息.
1). 通過兩條 sql 查詢:
select manager_id from employees where lower(last_name) = 'chen' -- 返回的結果爲 108 select * from employees where employee_id = 108
2). 通過一條 sql 查詢(自連接):
select m.* from employees e, employees m where e.manager_id = m.employee_id and e.last_name= 'Chen'
3). 通過一條 sql 查詢(子查詢):
select *
from employees
where employee_id = (
select manager_id
from employees
where last_name = 'Chen'
)
查詢平均工資高於 8000 的部門 id 和它的平均工資.
SELECT department_id, avg(salary) FROM employees e GROUP BY department_id HAVING avg(salary) > 8000
4. 查詢工資最低的員工信息:last_name, salary
SELECT last_name, salary
FROM employees
WHERE salary = ( SELECT min(salary) FROM employees )
5.查詢平均工資最低的部門信息
SELECT *
FROM departments
WHERE department_id =(
SELECT department_id
FROM employees
GROUP BY department_id
HAVING avg(salary) =(
SELECT min(avg(salary))
FROM employees
GROUP BY department_id )
)
6.查詢平均工資最低的部門信息和該部門的平均工資
select d.*, (select avg(salary) from employees where department_id = d.department_id) from departments d where d.department_id = ( SELECTdepartment_id FROM employees GROUP BY department_id HAVING avg(salary) =( SELECT min(avg(salary)) FROM employees GROUP BY department_id ) )
7.查詢平均工資最高的 job 信息
1). 按 job_id 分組, 查詢最高的平均工資
2). 查詢出平均工資等於 1) 的 job_idSELECT max(avg(salary)) FROM employees GROUP BY job_id
SELECT job_id FROM employees GROUP BYjob_id HAVING avg(salary) = ( SELECT max(avg(salary)) FROM employees GROUP BY job_id )
3). 查詢出 2) 對應的 job 信息
SELECT *
FROM jobs
WHERE job_id = (
SELECT job_id
FROM employees
GROUP BY job_id
HAVING avg(salary) = (
SELECT max(avg(salary))
FROM employees
GROUP BY job_id )
)
8.查詢平均工資高於公司平均工資的部門有哪些?
1). 查詢出公司的平均工資
SELECT avg(salary) FROM employees
2). 查詢平均工資高於 1) 的部門 ID
SELECT department_id FROM employees GROUP BY department_id HAVING avg(salary) > ( SELECT avg(salary) FROMemployees)
9.查詢出公司中所有 manager的詳細信息.(IN關鍵字)
1). 查詢出所有的 manager_id
SELECT distinct manager_id FROM employeess
2). 查詢出 employee_id 爲 1) 查詢結果的那些員工的信息
SELECT employee_id, last_name FROM employees WHERE employee_id in ( SELECT distinct manager_id FROM employees )
10.各個部門中 最高工資中最低的那個部門的最低工資是多少
1). 查詢出各個部門的最高工資
SELECT max(salary) FROM employees GROUP BY department_id
2). 查詢出 1) 對應的查詢結果的最低值: 各個部門中最低的最高工資(無法查詢對應的 department_id)
SELECT min(max(salary)) FROM employees GROUP BY department_id
3). 查詢出 2) 所對應的部門 id 是多少: 各個部門中最高工資等於的那個部門的 id
SELECT department_id FROM employees GROUP BY department_id HAVING max(salary) =( SELECT min(max(salary)) FROM employees GROUP BY department_id )
4). 查詢出 3) 所在部門的最低工資
SELECT min(salary) FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING max(salary) =( SELECT min(max(salary)) FROM employees GROUP BY department_id ) )
11.查詢平均工資最高的部門的manager 的詳細信息: last_name,department_id, email, salary
1). 各個部門中, 查詢平均工資最高的平均工資是多少
SELECT max(avg(salary)) FROM employees GROUP BY department_id
2). 各個部門中, 平均工資等於 1) 的那個部門的部門號是多少
SELECT department_id FROM employees GROUP BY department_id HAVING avg(salary) = ( SELECT max(avg(salary)) FROM employees GROUP BY department_id )
3). 查詢出 2) 對應的部門的manager_id
SELECT manager_id FROM departments WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING avg(salary) = ( SELECT max(avg(salary)) FROM employees GROUP BY department_id ) )
4). 查詢出 employee_id 爲 3) 查詢的 manager_id的員工的last_name, department_id, email, salary
SELECT last_name, department_id, email,salary FROM employees WHERE employee_id = ( SELECT manager_id FROM departments WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING avg(salary) = ( SELECT max(avg(salary)) FROM employees GROUP BY department_id ) ) )
12.查詢 1999 年來公司的人中所有員工的最高工資的那個員工的信息.
1). 查詢出 1999 年來公司的所有的員工的salary
SELECT salary FROM employees WHERE to_char(hire_date,'yyyy') = '1999'
2). 查詢出 1) 對應的結果的最大值
SELECT max(salary) FROM employees WHERE to_char(hire_date, 'yyyy') = '1999'
3). 查詢工資等於 2) 對應的結果且 1999 年入職的員工信息
SELECT * FROM employees WHERE to_char(hire_date, 'yyyy') = '1999' AND salary = ( SELECT max(salary) FROMemployees WHERE to_char(hire_date, 'yyyy') = '1999' )
13.返回其它部門中比 job_id 爲‘IT_PROG’部門所有工資都低的員工的員工號、姓名、job_id 以及 salary
SELECT employee_id, last_name, job_id,salary FROM employees WHERE salary< ALL (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id<> 'IT_PROG';
主要學會問題的拆分,由內而外 將大問題逐個拆分爲小問題。
2高級子查詢
******************高級子查詢******************
書寫多列子查詢
在 FROM 子句中使用子查詢
在 SQL 中使用單列子查詢
書寫相關子查詢
使用 EXISTS 和 NOT EXISTS 操作符
使用子查詢更新和刪除數據
使用 WITH 子句
1.多列子查詢(不成對比較& 成對比較)
1.查詢與 141 號或 174 號員工的 manager_id 和 department_id 相同的其他員工的 employee_id, manager_id, department_id
[方式一]
SELECT employee_id,manager_id, department_id FROM employees WHERE manager_id IN ( SELECT manager_id FROM employees WHERE employee_id IN(174,141) ) AND department_id IN ( SELECT department_id FROM employees WHERE employee_id IN(174,141)) AND employee_id NOTIN(174,141);
[方式二]
SELECT employee_id,manager_id, department_id FROM employees WHERE (manager_id,department_id) IN ( SELECTmanager_id, department_id FROM employees WHERE employee_id IN (141,174)) AND employee_id NOT IN (141,174);
2.在FROM 子句中使用子查詢
2.返回比本部門平均工資高的員工的 last_name, department_id, salary 及平均工資
[方式一]
select last_name,department_id,salary, (select avg(salary) from employees e3 where e1.department_id = e3.department_id groupby department_id ) avg_salary from employees e1 where salary >(select avg(salary) from employees e2 where e1.department_id = e2.department_id group by department_id )
[方式二]
SELECT a.last_name,a.salary, a.department_id, b.salavg FROM employees a, (SELECT department_id,AVG(salary) salavg FROM employees GROUP BYdepartment_id) b WHERE a.department_id =b.department_id AND a.salary> b.salavg
3.單列子查詢表達式
• Oracle8i只在下列情況下可以使用, 例如:
– SELECT 語句 (FROM 和 WHERE 子句)
– INSERT 語句中的 VALUES 列表中
• Oracle9i中單列子查詢表達式可在下列情況下使用:
– DECODE 和 CASE
– SELECT 中除 GROUP BY 子句以外的所有子句中
3. 顯示員工的employee_id,last_name 和location。其中,若員工department_id 與 location_id 爲1800 的 department_id 相同,則location 爲’Canada’,其餘則爲’USA’。
SELECT employee_id, last_name, ( CASE department_id WHEN ( SELECT department_id FROM departments WHERE location_id = 1800) THEN 'Canada' ELSE 'USA' END) location FROM employees;
4. 查 詢 員 工 的 employee_id,last_name, 要 求 按 照 員 工 的department_name 排序
SELECT employee_id,last_name FROM employeese ORDER BY (SELECT department_name FROM departments d WHERE e.department_id = d.department_id);
單列、from、orderby等都可以進行子查詢
4.相關子查詢
5.查詢員工中工資大於本部門平均工資的員工的 last_name,salary 和其 department_id
SELECT last_name, salary, department_id FROM employees outer WHERE salary > (SELECT AVG(salary) FROM employees WHERE department_id=outer.department_id);
6.若 employees 表中employee_id 與 job_history 表中employee_id相同的數目不小於 2,輸出這些相同 id 的員工的employee_id,last_name和其 job_id
SELECT e.employee_id, last_name,e.job_id FROM employees e WHERE 2<= (SELECT COUNT(*) FROM job_history WHERE employee_id =e.employee_id);
5.EXISTS 操作符
• EXISTS 操作符檢查在子查詢中是否存在滿足條件的行
• 如果在子查詢中存在滿足條件的行:
– 不在子查詢中繼續查找
– 條件返回 TRUE
7. 查詢公司管理者的employee_id,last_name,job_id,department_id 信息
SELECT employee_id, last_name, job_id, department_id FROM employees outer WHERE EXISTS ( SELECT 'X' FROM employees WHERE manager_id= outer.employee_id);
8. 查詢 departments 表中,不存在於 employees 表中的部門的department_id 和 department_name
SELECT department_id,department_name FROM departments d WHERE NOT EXISTS ( SELECT'X' FROM employees WHERE department_id =d.department_id);
6.關於數據更新
9.修改表 employees,添加department_name 列,賦予department_id相應的部門名稱。
ALTER TABLE employees ADD(department_name VARCHAR2(14)); UPDATE employees e SET department_name= ( SELECT department_name FROM departments d WHERE e.department_id= d.department_id);
7.關於數據刪除
10.刪除表 employees 中,其與emp_history 表皆有的數據
DELETE FROM employees E WHERE employee_id in( SELECT employee_id FROM emp_history WHERE employee_id =E.employee_id);
8.WITH 子句
11. 查詢公司中各部門的總工資大於公司中各部門的平均總工資的部門信息
WITH dept_costs AS ( SELECT d.department_name,SUM(e.salary) AS dept_total FROM employeese, departments d WHERE e.department_id= d.department_id GROUPBY d.department_name), avg_cost AS( SELECT SUM(dept_total) / COUNT(*) AS dept_avg FROM dept_costs) SELECT * FROM dept_costs WHERE dept_total> (SELECT dept_avg FROM avg_cost) ORDER BY department_name;
3 附加題目
NOTNULL/ALL/EXISTS/NOT EXISTS
12. 查詢員工的 last_name, department_id, salary. 其中員工的salary,department_id 與有獎金的任何一個員工的 salary,department_id 相同即可
select last_name, department_id, salary from employees where(salary,department_id) in ( select salary,department_id from employees where commission_pct is not null )
13.選擇工資大於所有 JOB_ID = 'SA_MAN' 的員工的工資的員工的last_name,job_id, salary
select last_name, job_id, salary from employees where salary > all( selectsalary from employees where job_id = 'SA_MAN' )
14.選擇所有沒有管理者的員工的 last_name
select last_name from employees e1 where not exists ( select 'A' from employees e2 where e1.manager_id = e2.employee_id )
15. 查詢 10,50,20 號部門的job_id,department_id 並且
department_id 按 10,50,20 的順序排列(union)
Column dummy noprint; select job_id , department_id ,1dummy from employees wheredepartment_id = 10 union select job_id , department_id , 2 from employees wheredepartment_id = 50 union select job_id , department_id , 3 from employees wheredepartment_id= 20 order by 3
4 總結
1 Having 和Where的區別
having 和where 都是用來篩選用的 ,但是having 是篩選組, 而where是篩選記錄。他們有各自的區別:
1》當分組篩選的時候用having
-----------------------------------------------------
用having就一定要和group by連用
用group by不一有having (它只是一個篩選條件用的)
-------------------------------------------------------
2》其它情況用where
3》where和having的執行級別不同
在查詢過程中聚合語句(sum,min,max,avg,count)要比having子句優先執行。
而where子句在查詢過程中優先於聚合語句(sum,min,max,avg,count)。
having就是來彌補where在分組數據判斷時的不足,因爲where執行優先級別要快於聚合語句。
2 With子句
with子句-----給子查詢定義一個別名,可以通過別名來引用子查詢,實現了一次定義多次使用。
WITH子句的格式爲: WITH 別名 AS(子查詢)
定義好別名就可以在sql中通過別名來引用子查詢