1. 程式人生 > >Oracle資料庫基礎學習DAY3

Oracle資料庫基礎學習DAY3

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