Oracle資料庫基礎學習DAY3
阿新 • • 發佈:2019-01-31
1、連線
用一個連線來從多個表中獲取資料。
select table.column,table2.column
from table1,table2
where table1.column1=table2.column2;
在where子句中書寫連線的條件。
如果某個列的名字在多個表中出現了,
那麼需要在列的名字前加上表名作為字首。
·內連線
捨棄不匹配的元組
select * from emp inner join dept on emp.deptno = dept.deptno;
·自然連線
合併相同欄位的列
select * from emp natural join dept;
·左外連線
內連線+左邊關係中失配的元組(缺少的右邊關係屬性值用null表示)
//左邊的表每項保留,右邊用null補齊
select * from emp left outer join dept on emp.deptno = dept.deptno;
·右外連線
內連線+右邊關係中失配的元組(缺少的左邊關係屬性值用null表示)
//右邊的表每項保留,左邊用null補齊
select * from emp e,dept d where e.deptno (+)= d.deptno;
·全連線
內連線+左邊關係中失配的元組(缺少的右邊關係屬性值用null表示)
+右邊關係中失配的元組(缺少的左邊關係屬性用null表示)
select * from emp full outer join dept on emp.deptno = dept.deptno;
·cross join
兩個關係的笛卡爾積。//嚴禁使用
注意:在三個以上數量的表連線時不要忘記各個表的連線條件
否則會產生笛卡爾積。
2、笛卡爾積
以笛卡爾積連線的表具有下列特徵:
·連線條件被忽略;
·第一個表的所有的行與第二個表中的所有行相連線。
如果在where子句中條件,那麼可以避免笛卡爾積
3、表的別名
select ename,e.deptno,d.loc from emp e,dept d where e.deptno=d.deptno;
//在from後面寫表名時用空格隔開別名,語句中其他位置必須使用別名
#############################練習#######################################
##單表查詢
1、查詢emp表中的所有資訊
select * from emp;
2、顯示emp表中的員工姓名和工資
select ename,sal from emp;
3、查詢emp表中部門編號為20的並且sal(工資)大於3000的所有員工資訊
select * from emp where deptno = 20 and sal > 3000;
4、查詢emp表中部門編號為20的或者sal(工資)大於3000的所有員工資訊
select * from emp where deptno = 20 or sal > 3000;
5、使用between and查詢工資在2000和4000之間的員工(用and重新實現)
select * from emp where sal between 2000 and 4000;
6、使用in 查詢部門編號10,20的所有員工
select * from emp where deptno in (10,20);
7、使用like查詢所有名字中包括W的員工資訊
select * from emp where ename like '%W%';
8、使用like查詢所有員工名字中第二個字母為W的員工資訊
select * from emp where ename like '_W%';
9、查詢所有員工資訊並按照部門編號和工資進行排序
select * from emp order by deptno,sal asc;
10、顯示員工工資上浮20%的結果。
select ename,sal,(emp.sal*1.2)as increase_sal from emp;
11、顯示emp表的員工姓名以及工資和獎金的和
select ename,sal+nvl(comm,0) as total_sal from emp;
12、顯示dept表的內容,使用別名將表頭轉換成中文顯示
select deptno 部門編號,dname 部門名字,loc 地點 from dept;
13、查詢員工姓名和工資,並按僱用日期排序,後僱用的先顯示
select ename 員工姓名,sal 工資 from emp order by hiredate desc;
14、查詢員工資訊,先按部門標號從小到大排序,再按僱用時間的先後排序
select * from emp order by deptno,hiredate asc;
########################多表查詢###########################################
1、列出在部門sales工作的員工的姓名
select emp.ename
from emp, dept
where emp.deptno = dept.deptno
and dept.dname = 'SALES';
2、列出所有員工的姓名,部門名稱和工資
select emp.ename, dept.dname, emp.sal
from emp, dept
where emp.deptno = dept.deptno;
3、列出所有部門的詳細資訊和部門人數
select dept.*, count(ename)
from emp, dept
where emp.deptno(+) = dept.deptno
group by dept.deptno, dname, loc;
4、列出各個部門職位為manager的最低薪金
select dept.dname, min(emp.sal)
from emp, dept
where emp.deptno = dept.deptno and job ='MANAGER'
group by dept.dname;
5、查詢出部門人數至少為1的部門名字
select distinct dept.dname
from emp, dept
where emp.deptno = dept.deptno
group by dept.dname
having count(ename) >= 1;
6、列出工資比Smith多的員工
select ename
from emp
where ename != 'SMITH'
and sal > (select sal from emp where ename = 'SMITH');
7、列出所有員工的對應領導的姓名
select e1.ename, e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno;
8、求出某個員工的領導,並要求這些領導的薪水高於或等於3000
select distinct e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno
where e2.sal >= 3000;
9、列出部門名稱,和這些部門的員工資訊
select dept.dname,
dept.deptno,
emp.empno,
emp.ename,
emp.job,
emp.mgr,
emp.hiredate,
emp.sal,
emp.comm
from emp
right join dept on emp.deptno = dept.deptno;
10、列出所有職位為clerk的員工姓名及其部門名稱,部門的人數
--子查詢部門名稱,人數
select dept.deptno, dname, count(ename)
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno,dname order by dept.deptno;
select emp.ename, a.dname, a.人數
from emp
left join (select dept.deptno, dname, count(ename) 人數
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno, dname) a on emp.deptno = a.deptno
where emp.job = 'CLERK';
11、列出薪金高於公司平均薪金的所有員工,所在部門,上級領導,公司的工資等級
select e.ename, d.dname, l.ename 上級領導, s.grade
from emp e, emp l, dept d, salgrade s
where e.deptno = d.deptno
and e.mgr = l.empno(+)
and e.sal > (select avg(sal) from emp)
and e.sal between s.losal and s.hisal;
12、列出與scott從事相同工作的所有員工及其部門名稱
select ename, dname
from emp, dept
where emp.deptno = dept.deptno
and job = (select job from emp where ename = 'SCOTT')
and ename != 'SCOTT';
13、列出薪金大於部門30中的任意員工的薪金的所有員工的姓名和薪金
select ename, sal
from emp
where sal > any (select sal from emp where deptno = 30);
14、列出薪金大於部門30中全部員工的薪金的所有員工的姓名和薪金,部門名稱
select ename, sal, dname
from emp, dept
where emp.deptno = dept.deptno
and sal > all (select sal from emp where deptno = 30);
15、列出每個部門的員工數量,平均工資
select dept.deptno,dept.dname, count(*), avg(sal)
from emp, dept
where emp.deptno = dept.deptno
group by dept.deptno,dept.dname
order by dept.deptno;
16、列出每個部門的員工數量,平均工資和平均服務期限(月)
select deptno,
count(*) 員工數量,
trunc(avg(sal + nvl(comm, 0))) 平均工資,
trunc(avg(sysdate - hiredate) / 30) 平均服務期限
from emp
group by deptno;
17、列出各種工作的最低工資及從事工資最低工作的僱員名稱
select ename
from emp
where (job, sal) in (select job, min(sal) from emp group by job);
18、求出部門名稱帶字元'S'的部門員工,工資合計,部門人數
select dept.deptno,
dept.dname 部門名稱,
sum(sal + nvl(comm, 0)) 工資合計,
count(ename) 部門人數
from emp, dept
where emp.deptno(+) = dept.deptno
and dname like '%S%'
group by dept.deptno, dname;
19、求出部門平均工資以及等級
select a.deptno, a.平均工資, s.grade
from (select deptno, trunc(avg(sal)) 平均工資 from emp group by deptno) a,
salgrade s where 平均工資 between s.losal and s.hisal;
20、不使用函式查詢工資最高人的資訊
----------(1)
select * from emp where sal >= all (select sal from emp);
----------(2)
select * from (select * from emp order by sal desc) where rownum = 1;
21、求出平均工資最高的部門名稱
-----(1)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname
from deptavgsal
where 平均工資 = (select max(平均工資) from deptavgsal);
-----(2)
select dname
from (select dname
from emp, dept
where dept.deptno = emp.deptno
group by dname
order by avg(sal + nvl(comm, 0)) desc)
where rownum = 1;
22、求平均工資的等級最低的部門名稱
------(1)
select dname
from (select dname, grade
from (select dname, avg(sal + nvl(comm, 0)) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname
order by avg(sal + nvl(comm, 0))),
salgrade
where 平均工資 between losal and hisal
order by grade)
where rownum = 1;
------(2)
select a.dname 部門名稱, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname) a,
salgrade
where 平均工資 between losal and hisal
and grade =
(select min(grade)
from (select b.dname 部門名稱, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname) b,
salgrade
where 平均工資 between losal and hisal));
------(3)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname 部門名稱, grade
from deptavgsal, salgrade
where 平均工資 between losal and hisal
and grade = (select min(grade)
from (select dname 部門名稱, grade
from deptavgsal, salgrade
where 平均工資 between losal and hisal));
23、部門經理人中平均工資最低的部門名稱
-------(1)
select dname
from (select dname, avg(工資)
from (select distinct l.ename,
l.deptno 部門編號,
l.sal + nvl(l.comm, 0) 工資
from emp e, emp l
where e.mgr = l.empno) m,
dept
where m.部門編號 = dept.deptno
group by dname
order by avg(工資))
where rownum = 1;
--------(2)
with mgravgsal as(
select 部門名稱, trunc(avg(工資)) 平均工資
from (select distinct l.ename 領導,
d.dname 部門名稱,
l.sal + nvl(l.comm, 0) 工資
from emp e, emp l, dept d
where e.mgr = l.empno
and l.deptno = d.deptno)
group by 部門名稱)
select 部門名稱
from mgravgsal
where 平均工資 = (select min(平均工資) from mgravgsal);
用一個連線來從多個表中獲取資料。
select table.column,table2.column
from table1,table2
where table1.column1=table2.column2;
在where子句中書寫連線的條件。
如果某個列的名字在多個表中出現了,
那麼需要在列的名字前加上表名作為字首。
·內連線
捨棄不匹配的元組
select * from emp inner join dept on emp.deptno = dept.deptno;
·自然連線
合併相同欄位的列
select * from emp natural join dept;
·左外連線
內連線+左邊關係中失配的元組(缺少的右邊關係屬性值用null表示)
//左邊的表每項保留,右邊用null補齊
select * from emp left outer join dept on emp.deptno = dept.deptno;
·右外連線
內連線+右邊關係中失配的元組(缺少的左邊關係屬性值用null表示)
//右邊的表每項保留,左邊用null補齊
select * from emp e,dept d where e.deptno (+)= d.deptno;
·全連線
內連線+左邊關係中失配的元組(缺少的右邊關係屬性值用null表示)
+右邊關係中失配的元組(缺少的左邊關係屬性用null表示)
select * from emp full outer join dept on emp.deptno = dept.deptno;
·cross join
兩個關係的笛卡爾積。//嚴禁使用
注意:在三個以上數量的表連線時不要忘記各個表的連線條件
否則會產生笛卡爾積。
2、笛卡爾積
以笛卡爾積連線的表具有下列特徵:
·連線條件被忽略;
·第一個表的所有的行與第二個表中的所有行相連線。
如果在where子句中條件,那麼可以避免笛卡爾積
3、表的別名
select ename,e.deptno,d.loc from emp e,dept d where e.deptno=d.deptno;
//在from後面寫表名時用空格隔開別名,語句中其他位置必須使用別名
#############################練習#######################################
##單表查詢
1、查詢emp表中的所有資訊
select * from emp;
2、顯示emp表中的員工姓名和工資
select ename,sal from emp;
3、查詢emp表中部門編號為20的並且sal(工資)大於3000的所有員工資訊
select * from emp where deptno = 20 and sal > 3000;
4、查詢emp表中部門編號為20的或者sal(工資)大於3000的所有員工資訊
select * from emp where deptno = 20 or sal > 3000;
5、使用between and查詢工資在2000和4000之間的員工(用and重新實現)
select * from emp where sal between 2000 and 4000;
6、使用in 查詢部門編號10,20的所有員工
select * from emp where deptno in (10,20);
7、使用like查詢所有名字中包括W的員工資訊
select * from emp where ename like '%W%';
8、使用like查詢所有員工名字中第二個字母為W的員工資訊
select * from emp where ename like '_W%';
9、查詢所有員工資訊並按照部門編號和工資進行排序
select * from emp order by deptno,sal asc;
10、顯示員工工資上浮20%的結果。
select ename,sal,(emp.sal*1.2)as increase_sal from emp;
11、顯示emp表的員工姓名以及工資和獎金的和
select ename,sal+nvl(comm,0) as total_sal from emp;
12、顯示dept表的內容,使用別名將表頭轉換成中文顯示
select deptno 部門編號,dname 部門名字,loc 地點 from dept;
13、查詢員工姓名和工資,並按僱用日期排序,後僱用的先顯示
select ename 員工姓名,sal 工資 from emp order by hiredate desc;
14、查詢員工資訊,先按部門標號從小到大排序,再按僱用時間的先後排序
select * from emp order by deptno,hiredate asc;
########################多表查詢###########################################
1、列出在部門sales工作的員工的姓名
select emp.ename
from emp, dept
where emp.deptno = dept.deptno
and dept.dname = 'SALES';
2、列出所有員工的姓名,部門名稱和工資
select emp.ename, dept.dname, emp.sal
from emp, dept
where emp.deptno = dept.deptno;
3、列出所有部門的詳細資訊和部門人數
select dept.*, count(ename)
from emp, dept
where emp.deptno(+) = dept.deptno
group by dept.deptno, dname, loc;
4、列出各個部門職位為manager的最低薪金
select dept.dname, min(emp.sal)
from emp, dept
where emp.deptno = dept.deptno and job ='MANAGER'
group by dept.dname;
5、查詢出部門人數至少為1的部門名字
select distinct dept.dname
from emp, dept
where emp.deptno = dept.deptno
group by dept.dname
having count(ename) >= 1;
6、列出工資比Smith多的員工
select ename
from emp
where ename != 'SMITH'
and sal > (select sal from emp where ename = 'SMITH');
7、列出所有員工的對應領導的姓名
select e1.ename, e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno;
8、求出某個員工的領導,並要求這些領導的薪水高於或等於3000
select distinct e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno
where e2.sal >= 3000;
9、列出部門名稱,和這些部門的員工資訊
select dept.dname,
dept.deptno,
emp.empno,
emp.ename,
emp.job,
emp.mgr,
emp.hiredate,
emp.sal,
emp.comm
from emp
right join dept on emp.deptno = dept.deptno;
10、列出所有職位為clerk的員工姓名及其部門名稱,部門的人數
--子查詢部門名稱,人數
select dept.deptno, dname, count(ename)
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno,dname order by dept.deptno;
select emp.ename, a.dname, a.人數
from emp
left join (select dept.deptno, dname, count(ename) 人數
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno, dname) a on emp.deptno = a.deptno
where emp.job = 'CLERK';
11、列出薪金高於公司平均薪金的所有員工,所在部門,上級領導,公司的工資等級
select e.ename, d.dname, l.ename 上級領導, s.grade
from emp e, emp l, dept d, salgrade s
where e.deptno = d.deptno
and e.mgr = l.empno(+)
and e.sal > (select avg(sal) from emp)
and e.sal between s.losal and s.hisal;
12、列出與scott從事相同工作的所有員工及其部門名稱
select ename, dname
from emp, dept
where emp.deptno = dept.deptno
and job = (select job from emp where ename = 'SCOTT')
and ename != 'SCOTT';
13、列出薪金大於部門30中的任意員工的薪金的所有員工的姓名和薪金
select ename, sal
from emp
where sal > any (select sal from emp where deptno = 30);
14、列出薪金大於部門30中全部員工的薪金的所有員工的姓名和薪金,部門名稱
select ename, sal, dname
from emp, dept
where emp.deptno = dept.deptno
and sal > all (select sal from emp where deptno = 30);
15、列出每個部門的員工數量,平均工資
select dept.deptno,dept.dname, count(*), avg(sal)
from emp, dept
where emp.deptno = dept.deptno
group by dept.deptno,dept.dname
order by dept.deptno;
16、列出每個部門的員工數量,平均工資和平均服務期限(月)
select deptno,
count(*) 員工數量,
trunc(avg(sal + nvl(comm, 0))) 平均工資,
trunc(avg(sysdate - hiredate) / 30) 平均服務期限
from emp
group by deptno;
17、列出各種工作的最低工資及從事工資最低工作的僱員名稱
select ename
from emp
where (job, sal) in (select job, min(sal) from emp group by job);
18、求出部門名稱帶字元'S'的部門員工,工資合計,部門人數
select dept.deptno,
dept.dname 部門名稱,
sum(sal + nvl(comm, 0)) 工資合計,
count(ename) 部門人數
from emp, dept
where emp.deptno(+) = dept.deptno
and dname like '%S%'
group by dept.deptno, dname;
19、求出部門平均工資以及等級
select a.deptno, a.平均工資, s.grade
from (select deptno, trunc(avg(sal)) 平均工資 from emp group by deptno) a,
salgrade s where 平均工資 between s.losal and s.hisal;
20、不使用函式查詢工資最高人的資訊
----------(1)
select * from emp where sal >= all (select sal from emp);
----------(2)
select * from (select * from emp order by sal desc) where rownum = 1;
21、求出平均工資最高的部門名稱
-----(1)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname
from deptavgsal
where 平均工資 = (select max(平均工資) from deptavgsal);
-----(2)
select dname
from (select dname
from emp, dept
where dept.deptno = emp.deptno
group by dname
order by avg(sal + nvl(comm, 0)) desc)
where rownum = 1;
22、求平均工資的等級最低的部門名稱
------(1)
select dname
from (select dname, grade
from (select dname, avg(sal + nvl(comm, 0)) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname
order by avg(sal + nvl(comm, 0))),
salgrade
where 平均工資 between losal and hisal
order by grade)
where rownum = 1;
------(2)
select a.dname 部門名稱, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname) a,
salgrade
where 平均工資 between losal and hisal
and grade =
(select min(grade)
from (select b.dname 部門名稱, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname) b,
salgrade
where 平均工資 between losal and hisal));
------(3)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工資
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname 部門名稱, grade
from deptavgsal, salgrade
where 平均工資 between losal and hisal
and grade = (select min(grade)
from (select dname 部門名稱, grade
from deptavgsal, salgrade
where 平均工資 between losal and hisal));
23、部門經理人中平均工資最低的部門名稱
-------(1)
select dname
from (select dname, avg(工資)
from (select distinct l.ename,
l.deptno 部門編號,
l.sal + nvl(l.comm, 0) 工資
from emp e, emp l
where e.mgr = l.empno) m,
dept
where m.部門編號 = dept.deptno
group by dname
order by avg(工資))
where rownum = 1;
--------(2)
with mgravgsal as(
select 部門名稱, trunc(avg(工資)) 平均工資
from (select distinct l.ename 領導,
d.dname 部門名稱,
l.sal + nvl(l.comm, 0) 工資
from emp e, emp l, dept d
where e.mgr = l.empno
and l.deptno = d.deptno)
group by 部門名稱)
select 部門名稱
from mgravgsal
where 平均工資 = (select min(平均工資) from mgravgsal);