1. 程式人生 > >快速提升sql能力

快速提升sql能力

  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

***對應答案

  1. 查詢每個月倒數第 2 天入職的員工的資訊.

select last_name, hire_date from employees where hire_date = last_day(hire_date) – 1

  1. 查詢出 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’ )

  1. 查詢平均工資高於 8000 的部門 id 和它的平均工資.

SELECT department_id, avg(salary) FROM employees e GROUP BY department_id HAVING avg(salary) > 8000

  1. 查詢工資最低的員工資訊: last_name, salary

SELECT last_name, salary FROM employees WHERE salary = ( SELECT min(salary) FROM employees )

  1. 查詢平均工資最低的部門資訊

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  )  ) 
  1. 查詢平均工資最低的部門資訊和該部門的平均工資

select d.*, (select avg(salary) from employees where department_id = d.department_id)

from departments d where d.department_id = ( SELECT department_id FROM employees GROUP

BY department_id HAVING avg(salary) = ( SELECT min(avg(salary)) FROM employees

 GROUP BY department_id      )        )    
  1. 查詢平均工資最高的 job 資訊

1). 按 job_id 分組, 查詢最高的平均工資

SELECT max(avg(salary)) FROM employees GROUP BY job_id

2). 查詢出平均工資等於 1) 的 job_id

SELECT job_id FROM employees GROUP BY job_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 ) )

  1. 查詢平均工資高於公司平均工資的部門有哪些?

1). 查詢出公司的平均工資

SELECT avg(salary) FROM employees

2). 查詢平均工資高於 1) 的部門 ID

SELECT department_id FROM employees GROUP BY department_id HAVING avg(salary) > (

SELECT avg(salary) FROM employees )

  1. 查詢出公司中所有 manager 的詳細資訊.
    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 )

  1. 各個部門中 最高工資中最低的那個部門的 最低工資是多少
    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 是多少: 各個部門中最高工資等於
2) 的那個部門的 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 ) )

  1. 查詢平均工資最高的部門的 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 ) ) )

  1. 查詢 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) FROM employees WHERE to_char(hire_date, ‘yyyy’) = ‘1999’ )

  1. 返回其它部門中比 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’;

高階子查詢

• 書寫多列子查詢
• 在 FROM 子句中使用子查詢
• 在 SQL 中使用單列子查詢
• 書寫相關子查詢
• 使用 EXISTS 和 NOT EXISTS 操作符
• 使用子查詢更新和刪除資料
• 使用 WITH 子句
–多列子查詢(不成對比較 & 成對比較) 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 NOT IN(174,141);

[方式二]

SELECT employee_id, manager_id, department_id FROM employees WHERE (manager_id,

department_id) IN SELECT manager_id, department_id FROM employees

WHERE employee_id IN (141,174)) AND employee_id NOT IN (141,174);

–在 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 group by 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 BY department_id) b WHERE a.department_id = b.department_id

AND a.salary > b.salavg;

–單列子查詢表示式
• 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;

  1. 查詢員工的 employee_id,last_name, 要求按照員工的
    department_name 排序

SELECT employee_id, last_name FROM employees e

ORDER BY (SELECT department_name FROM departments d WHERE e.department_id =

d.department_id);

–相關子查詢

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) ; 
  1. 若 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);

–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);

  1. 查詢 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);

–關於資料更新
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);

–關於資料刪除
10.刪除表 employees 中,其與 emp_history 表皆有的資料

DELETE FROM employees E WHERE employee_id in (SELECT employee_id FROM

emp_history WHERE employee_id = E.employee_id);

–WITH 子句
11. 查詢公司中各部門的總工資大於公司中各部門的平均總工資的部門資訊 WITH

dept_costs AS ( SELECT d.department_name, SUM(e.salary) AS dept_total FROM

employees e, departments d WHERE e.department_id = d.department_id GROUP BY

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;

附加題目:
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(

select salary 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 的順序排列
Column dummy noprint;

select job_id , department_id ,1 dummy from employees where department_id = 10 union

select job_id , department_id , 2 from employees where department_id = 50 union

select job_id , department_id , 3 from employees where department_id= 20 order by 3