oracle課堂筆記--第十三天
自連接:
empid ename mgrid
100 abc
101 def 100
102 xyz 100
emp: mgr:
empid ename mgrid empid mgrname
100 abc 100 abc
101 def 100
102 xyz 100
101 def 100 100 abc
102 xyz 100 100 abc
select emp.ename, mgr.mgrname
from emp, mgr
where emp.mgrid=mgr.empid
emp: mgr:
empid ename mgrid empid ename mgrid
100 abc 100 abc
101 def 100 101 def 100
102 xyz 100 102 xyz 100
select e.last_name, m.last_name
from employees e, employees m
where e.manager_id=m.employee_id;
有經理的員工數:106
SQL> select count(*) from employees where manager_id is not null;
沒有經理的員工數:1
SQL> select count(*) from employees where manager_id is null;
練習:
顯示所有員工姓名和經理姓名,沒有經理的顯示“無”。
select e.last_name, nvl(m.last_name, ‘N/A‘)
from employees e, employees m
where e.manager_id=m.employee_id(+);
不等值連接:
conn scott/tiger
select e.ename, sg.grade
from emp e, salgrade sg
where e.sal between sg.losal and sg.hisal;
練習:
找出工資大於所在部門平均工資的員工姓名。
create table avg_sal_dept as select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id;
select e.last_name, e.salary, asd.avg_sal
from employees e, avg_sal_dept asd
where e.department_id=asd.department_id
and e.salary>asd.avg_sal;
select e.last_name, e.salary, asd.avg_sal
from employees e, (select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id) asd 給部門平均工資取別名!
where e.department_id=asd.department_id
and e.salary>asd.avg_sal;
子查詢
第一寫成子查詢 第二寫成主查詢
單行子查詢的思路:
SQL> select salary from employees where last_name=‘Feeney‘;
SQL> select last_name from employees where salary>3000;
SQL> select last_name from employees where salary>(select salary from employees where last_name=‘Feeney‘);
多行子查詢的思路:
SQL> select distinct department_id from employees where department_id is not null;
SQL> select department_name from departments where department_id in (10, 20,30);
SQL> select department_name from departments where department_id in (select department_id from employees where department_id is not null);
用多表連接改寫:
select distinct d.department_name
from employees e, departments d
where e.department_id=d.department_id
for dept in 1..27
for emp in 1..107
查看emp中是否出現deptid
練習:
工資大於全公司平均工資的員工姓名。
SQL> select last_name from employees where salary>(select avg(salary) from employees);
和Feeney同年入職的員工姓名
select last_name, hire_date
from employees
where extract(year from hire_date)=
(select extract(year from hire_date) from employees where last_name=‘Feeney‘)
and last_name != ‘Feeney‘;
select last_name, hire_date
from employees
where hire_date between
(select to_date(to_char(hire_date, ‘yyyy‘)||‘0101‘, ‘yyyymmdd‘) from employees where last_name=‘Feeney‘)
And
(select to_date(to_char(hire_date, ‘yyyy‘)||‘1231‘, ‘yyyymmdd‘) from employees where last_name=‘Feeney‘)
在Seattle工作的所有員工姓名
在Seattle的部門1 Seattle的location id是多少 2 location id 下的部門信息
在這些部門中的員工 1 那些部門 2 這些部門的員工
select last_name
from employees
where department_id in
(select department_id from departments
where location_id=
(select location_id from locations where city=‘Seattle‘));
查找符合下列條件的員工姓名:和Abel在同一個部門,工資比Olson高
select last_name from employees
where department_id=
(select department_id from employees where last_name=‘Abel‘)
and salary >
(select salary from employees where last_name=‘Olson‘);
配對子查詢:
和Feeney在同一個部門、做同一職位的員工姓名:
select last_name, department_id, job_id
from employees
where department_id=
(select department_id from employees where last_name=‘Feeney‘)
and job_id=
(select job_id from employees where last_name=‘Feeney‘)
and last_name != ‘Feeney‘;
select last_name, department_id, job_id
from employees
where (department_id, job_id)=
(select department_id, job_id from employees where last_name=‘Feeney‘)
and last_name != ‘Feeney‘;
in和not in受null值的影響:
有員工的部門名稱
select department_name from departments where department_id in (select department_id from employees);
沒有員工的部門名稱select department_name from departments where department_id not in (select department_id from employees where department_id is not null);
所有管理,者的姓名:
SQL> select last_name from employees where employee_id in (select manager_id from employees);
所有普通員工的姓名:
SQL> select last_name from employees where employee_id not in (select manager_id from employees where manager_id is not null);
關聯子查詢:
工資大於所在部門平均工資的員工姓名。
for i in 1..107所有員工
{
select avg(salary) from employees where department_id=i.department_id
if i.salary > i所在部門的平均工資
保留此記錄
}
select last_name
from employees outer
where salary >
(select avg(salary) from employees
where department_id = outer.department_id);
select e.last_name, e.salary, asd.avg_sal
from employees e, (select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id) asd
where e.department_id=asd.department_id
and e.salary>asd.avg_sal;
exists/not exists查詢: 是否存在
for i in 1..27所有部門
{
for j in 1..107所有員工
{
if i.department_id = j.department_id
保留此記錄
break
}
}
select department_name
from departments outer
where exists
(select 1 from employees where department_id=outer.department_id);
select department_name
from departments outer
where not exists
(select 1 from employees where department_id=outer.department_id);
練習:
在Seattle工作的所有員工姓名(使用子查詢和多表連接兩種方式)
select last_name
from employees
where department_id in
(select department_id from departments
where location_id=
(select location_id from locations where city=‘Seattle‘));
select e.last_name
from employees e, departments d, locations l
where e.department_id=d.department_id
and d.location_id=l.location_id
and l.city=‘Seattle‘;
最大值查詢:
SQL> select last_name from employees where salary=(select max(salary) from employees);
top-N查詢:
SQL> select last_name, salary from employees where rownum<=3 order by salary desc;
SQL> select * from (select last_name, salary from employees order by salary desc) where rownum<=3;
分頁查詢:
SQL> select * from
(select * from
(select * from
(select last_name, salary from employees order by salary desc)
where rownum<=6)
order by salary)
where rownum<=3
order by salary desc;
SQL> select last_name, salary
from (select rownum row_num, v1.*
from
(select last_name, salary from employees order by salary desc) v1
) v2
where row_num between 4 and 6;
select last_name, salary
from (select rownum row_num, v1.*
from
(select last_name, salary from employees order by salary desc) v1
where rownum<=6
) v2
where row_num >= 4;
oracle課堂筆記--第十三天