總結:
一:安裝oracle
Linux系統要求:
內存,CPU,足夠的大。
物理內存:必須高於1G,對於VMware虛擬機不少於1.5G。
一:基礎內容
1:SYS:SYS用戶是Oracle中的一個超級用戶。
system:system用戶是Oracle中默認數據庫管理員。
scott:scott是Oracle數據庫中一個示範用戶。
1:設置每行顯示的數據長度:SET LINESIZE 300;
設置每次顯示的行數:SET PAGESIZE 30;
查看當前用戶:
show user;
切換用戶:
CONN system/manager 鏈接用戶和密碼
sqlplus /nolog
CONN sys/change_on_install as sysdba
拷貝本機
copy e:\date e:\hello.sql
DML(數據操作語言):數據的更新與操作(select、from、insert、group by、delete)
DDL(數據定義語言):數據庫對象的定義語言、如:數據表、約束、索引、同義詞
DLC(數據庫控制語言):數據庫的權限控制
--------------------------------------------------------------------------------------------------
1、啟動監聽
[[email protected] ~]$ : lsnrctl
參數:
start:啟動監聽進程
stop:停止監聽進程
status:查看監聽進程狀態
reload:重新加載監聽進程
set:設置相應參數
help:顯示幫助信息。
version:顯示當前監聽進程版本
change_password:修改口令
2、關閉監聽
[[email protected] ~]$ : lsnrctl stop
總結:先啟動監聽、後啟動數據庫。
select語句:
select * from scott.dept; /查看scott.dept表中的全局信息。
describe scott.emp; /查看scott.dept表詳細信息。
select ename from scott.dept; /查看scott.dept表已dname顯示出列。
select enmae,sal from scott.emp; /查看scott.emp表中所有人的姓名和工資。
select ename,sal*12 “一年工資” from scott.emp; /查看scott.emp表中所有人的姓名和工資並乘12,並且加上名稱。
select deptno from scott.emp; /顯示部門的編號
select DISTINCT deptno from scott.emp;/顯示部門的編號並且不重復。
select ename,job from scott.emp; /顯示scott.emp表中所有人名字和工作類型。
select ename || ‘ ‘ ||job from scott.emp; /查看scott.emp表,結果是:SMITH CLARK 名字和工作在一行顯示,並且名字也有變化。
select ename || ‘工資’ || sal from scott.tmp;/查看scott.tmp表中的姓名-工資-金額#工資是夾在中間的別名。
select ‘編號:’ || empno || ‘,姓名: ’ || ename form scott.emp; /結果:編號:7369,姓名:SMITH
select ename || ‘工資’ || sal || ‘.‘ from scott.tmp;/查看scott.tmp表中的姓名-工資-金額。#工資是夾在中間的別名。
sql 限定查詢語句條件:
阿拉伯數據和字母的區別:
阿拉伯數字帶引號和不帶引號都一樣,阿拉伯數字針對於工資,而字母必須加引號,引號多對於人員名稱等信息,而且必須和表中的一致,表中是大寫必須填寫大寫。
1:確定數據的來源
2:篩選數據行
3:選出所需要的數據列
1:關系運算:>、=、<、>=、<=、!=或者<>;
範圍運算:BETWEEN....AND;
空格判斷:IS NULL ,IS NOT NULL。
IN 判斷:IN、NOT IN 、exists()(復雜查詢);
模糊查詢:LIKE、NOT LIKE。
邏輯運算:AND與、OR或、NOT非
與操作表示的所有的判斷條件滿足時返回真(true);
或操作表示若幹個判斷條件只要有一個滿足就返回真(true)。
s
select * from scott.emp where deptno=10; /顯示scott.emp表中部門是10的人員信息;
select * from scott.emp where deptno=‘10’; /顯示scott.emp表中部門是10的人員信息;
select * from scott.emp where ename=‘ALLEN’; /顯示scitt.emp表中名字是ALLEN的列出信息;
select 5+4*7 “結果” from dual; /計算5+4*7的結果,dual相當於空表。也可以理解為回收站。
select sysdata from dual; /顯示日期。格式:號-月-年
select * from scott.emp where hiredate > ‘01-JAN-87‘; /查看scott.tmp表中大於一號一月1987年的入職日期;
select * from scott.emp where sal <= 1000; /查看scott.emp表中工資小於等於1000的工資。
select * from scott.emp where sal >=2500 and sal <= 3500; /查看scott.emp表中公司大於2500並小於3500工資的列出。
select * from scott.emp where sal between 2500 and 3500; /查看scott.emp表中公司大於2500並小於3500工資的列出。
select * from scott.emp where sal = 800 or sal = 950; /查看工資等於絕對金額,其他的則不顯示。
select * from scott.emp where sal in (800,950); /查看工資等於絕對金額,其他的則不顯示。
select * from scott.emp where sal != 800 and sal != 950; /顯示金額不等於800和950的。則其他的顯示。
select * from scott.emp where job<>‘CLERK’ and sal<3000; /查詢scott.emp表,不查找CLERK的信息,並且公司不小於3000;
select * from scott.emp where sal not in (800,950); /顯示金額不等於800和950的。則其他的顯示。
select * from scott.emp where ename = ‘ALLEN‘; /顯示scott.emp表中ALLEN用戶的全部信息。
like 可以實現數據的模糊查詢操作,如果想使用like則不行使用如下兩個符號:
_:匹配任意的一位符號;
%;匹配任意的符號(包含匹配0位、1位、多位)
select * from scott.emp where ename = ‘ALLEN‘; /查找ALLEN的信息
select * from scott.emp where ename like ‘_A%‘; /_表示站一位字符,A表示帶A字母的、%表示其他。
select * from scott.emp where ename not like ‘A%‘; /A表示帶A字母開頭的英文名稱不會顯示。
select * from scott.emp where deptno like ‘10’; /查詢scott.emp表中查詢編號10
select * from scott.emp where comm is not null; /查看scott.emp表中COMM選項中不是空值的顯示出來。
select * from scott.emp order by sal asc; /查看scott.emp表中的工資,順序是升序,從少到多。
select * from scott.emp order by sal desc; /查看scott.emp表中的工資,順序是降序,從多到少。
select * from scott.emp order by deptno asc, sal desc; /查看scitt.emp表中部門為升序,工資為降序。
select * from scott.emp order by 8 asc, 6 desc; /查看scitt.emp表中部門為升序,工資為降序。這種方式用的很少。
select count(*) from scott.emp /統計表中有多少行
----------------------------------------------------------------------------------------------------------------------
oracle變量;
&a = 臨時變量
&&a = 永久變量
刪除永久變量方法:define abc = sal;?????????????????????
select * from scott.emp; /查看一個表的全局信息。
select empno, ename, hiredate, deptno from scott.emp where ename = ‘&bl01‘; /查看ename中的一個名稱,則顯示張三的empno, ename, hiredate, deptno內容。
select empno, ename, deptno, sal from scott.emp where sal > &bl01 order by &bl02 asc; /第一個環境變量輸入金額,第二個輸入工資則排序。
select empno, ename, deptno, &&abc from scott.emp order by &abcd; /首先輸入第一個變量的內容,可以是 empno, ename, deptno,然後調用,輸入1、2、3。
select &abc from scott.emp; /調用表中個的關鍵字,如empno, ename, deptno, sal。
define abc = sal; /替換變量,針對永久變量‘&&‘
select 3+5 "jieguo" from dual; /簡單的計算,dual相當於空表。
select sysdate from dual; /顯示系統時間
select ‘aa‘ || ‘bb‘ from dual; /結果是aabb。
字符串函數:
select initcap(‘guodongdong‘) from dual; /返回字符串並將字符串的第一個字母變為大寫;
select initcap(ename) from scott.emp; /針對scott.emp表中的ename開頭全部大寫。
select lower(ename) from scott.emp; /針對scott.emp表中的ename名字中全部小寫。
select upper(ename) from scott.emp; /針對scott.emp表中的ename名字全部大寫
select length(ename) from scott.emp; /查詢scott.emp表中的ename名字所占的單詞個數。
select ename,substr(ename,length(ename)-2) from scott.emp /查詢Scott.emp表中的ename名字最後的三個英文名稱。
或者 select ename,substr(ename,-3) from scott.emp;
select concat(‘guo‘,‘dongdong‘) from dual; /CONCAT只能連接兩個字符串,沒有|| 強大。
select concat(ename,sal) from scott.emp; /針對scott.emp表中的名字個工資做一個連接。
select substr(‘guodongdong‘,1,5) from dual; /查詢guodongdong,1-5的單詞列出。
select lpad(‘guodongdong‘,15,‘*‘) from dual; /顯示guodongdong,15表示15為,不夠15為則在前方補*。
select rpad(‘guodongdong‘,15,‘*‘) from dual; /顯示guodongdong,15表示15為,不夠15為則在後方補*。
select replace(‘guodongdong‘,‘d‘,‘j‘) from dual; /修改guodongdong,d單詞全部替換為j,則是guojongjong
select trim(‘k‘ from ‘gkgguodonkkgdonggg‘) from dual; /只要gkgguodonkkgdonggg去除指定字符的前後空格。
數值函數:
三個主要函數:ROUND,trunc,mod
1: SELECT
round(78915.67823823), 78916,小數點之後的內容直接進行四舍五入
round(78915.67823823,2), 78915.68,保留兩位小數
round(78915.67823823,-2), 78900,把不足5的數據取消了
round(78985.67823823,-2), 79000,如果超過了5則進行進位
round(-15.65) ; -16
from dual;
2:截取小數,所有的小數都不進位
SELECT
trunc(78915.67823823), 78916,小數點之後的內容直接進行四舍五入
trunc(78915.67823823,2), 78915.68,保留兩位小數
trunc(78915.67823823,-2), 78900,把不足5的數據取消了
trunc(78985.67823823,-2), 79000,如果超過了5則進行進位
trunc(-15.65) ; -16
from dual;
3:求模(求余數)
select mod(10,3) from dual; 得1
-----------------------------------------------------------------------------------------------------------------------------
日期函數:(oracle 自己特色)
select ename,hiredate,sysdate from scott.emp ; 可以查詢出員工入職到現在的日期
select sysdate,systimestamp dual;
實際上對於日期提供以下三種計算模式:
日期+數字=日期(若幹天之後的日期)
select sysdate +10 from dual;
日期-數字=日期(若幹天之前的日期)
select sysdate -10 from dual;
日期-日期=數字(兩個日期期間的天數)
計算每一位雇員到今天為止的雇傭天數。
select ename,hiredate, sysdate-hiredate form scott.emp
計算兩個日期見所經歷的月數總和。
語法:數字 MONTHS_BETWEEN(日期1,日期2)
MONTHS_BETWEEN函數返回兩個日期之間的月份數。
1:範例: 計算每一位員工到今天為止雇傭總月數。
select ename,hiredate,
trunc(months_between(sysdate,hiredate)/12) years from scott.emp
2:增加若幹月之後的日期;
範例:測試ADD_MONTHS函數
select add_months(sysdate,4) from dual;
3:計算還要差1年滿34年的雇傭日期的全部雇傭。
select * from scott.emp
where trunc(months_between(sysdate,hiredate)/12)=34 ; ?????????????????????????
4:計算指定日期所在月的最後一天
select last_day(sysdate) from dual;
5:查詢出所有雇傭所在月的倒數第二天被雇傭的雇員信息
每個雇員的雇傭日期是不一樣的,所有每一個雇傭日期所在月的倒數第二天也不一樣。
select ename,hiredate,last_day(hiredate),last_day(hiredate)-2 from scott.emp;
6:計算下一個周二
select next_day(sysdate,‘星期二’) from dual;
7:計算scott.emp表中雇傭的員工到目前為止的雇傭年份:
select empno,ename,hiredate, trunc(months_between(sysdate,hiredate)/12) year from scott.emp
8:綜合分析:要求查詢出雇員的編號、姓名、雇傭日期,以及每一位雇員到今天為止被雇傭的年數,月數天數。
假設下載的日期是:2016-03-08.
select empno,ename,hiredate,
trunc(months_between(sysdate,hiredate)/12) gear,
trunc(mod(months_between(sysdate,hiredate,)/12)) months,
trunc(sysdate-add_months(hiredate,months_between(sysdate,hiredate))) day
from scott.emp;
轉換函數:
三種:to_char、to_date、to_number。
yyyy-mm-dd-hh24-mi-ss
1: 格式化日期:
select to_char(sysdate,‘yyyy-mm-dd’) from dual;
2: 查詢出所有在2月雇傭的日期
select * from scott.emp where to_char(hiredate,‘mm‘)=‘02‘;
3: 轉換數字
select to_char(12345,‘L000,000,000.99999‘) from dual;
轉日期函數:
1:實現字符串轉換為日期
select to_date (‘1998-09-19’,‘yyyy-mm-dd’) from dual;
轉數字函數:
可以將字符串(由數字所組成)變為數字,語法:數字 to_number(字符串)
範例:
select to_number (‘1’) + to_number(‘2’) from dual;
select ‘1’ + ‘2’ from dual;
sekect sysdate + 3/24 from dual;
select to_char(sysdate,‘yyyy-mm-dd:fmhh24:mi:ss‘) from dual; /顯示時間年-月-日-小時-分鐘-秒,加fm則不顯示0。
select to_char(hiredate, ‘ss:yyyy+mm+dd‘) from scott.emp; ??????????????????????????
select to_char(hiredate, ‘ss:yyyy+mm+dd‘) from scott.emp; alter session set nls_date_format=‘yyyy-mm-dd:hh24:mi:ss‘ ????
select to_char(12345,‘L000,000,000.99999‘) from dual; ????????????????
select ename, hiredate from scott.emp where hiredate < ‘2010-1-1‘; /列出scott.emp表中入職人員和時間的日期小於2010-1-1。
select to_number(‘$124.00‘,‘$999.99‘) from dual; /主要是將字符串轉換為數值型的格式,與TO_CHAR()函數的作用正好相反。
select nvl(comm,4) from scott.emp; /通過查詢獲得某個字段的合計值,如果這個值位null將給出一個預設的默認值
select nvl2(3,1,2) from dual; ??????????????????
NVL2(expr1,expr2,expr3)
如果參數表達式expr1值為NULL,則NVL2()函數返回參數表達式expr3的值;如果參數表達式expr1值不為NULL,則NVL2()函數返回參數表達式expr2的值。
select nullif(4,5) from dual; /如果表達式1和表達式2相等則返回空值,如果表達式1和表達式2不相等則返回表達式1的結果。
select coalesce(1,null,null,null,4,5,null) from dual; /語法為COALESCE(表達式1,表達式2,...,表達式n),
n>=2,此表達式的功能為返回第一個不為空的表達式,如果都為空則返回空值。
---------------------------------------------------------------------------------------------------------------------------------
select last_name,job_id, salary, /查找名字、工作id、工資。
case job_id when ‘SH_CLERK‘ then 1.2*salary /案列 job_id 什麽時候 ‘SH_CLERK’ 然後 工資乘以1.2
when ‘AD_ASST‘ then 1.5*salary /什麽時候 ‘AD_SAAT’ 然後 工資乘以1.5
when ‘MK_MAN‘ then 2*salary /什麽時候 ‘MK_MAN’ 然後 工資乘以1.5
else salary end "chuli" /其他工資不變,結束,別名處理。
from hr.employees; /選擇表名
------------------------------------
疑問:
1:select ename, hiredate from scott.emp where hiredate > to_date(‘17-DEC-80‘); /加入日期是2015-12-26格式,使用這種格式查找不出來嗎?
2:select nvl2(3,1,2) from dual;
3:select last_name,salary,
decode( trunc(salary/2000),0,‘xiaoyu liangqian‘,
1,‘yi bei‘,
2,‘er bei‘,
‘buguanzhu‘) "chuli"
from hr.employees;
IN操作符
IN指的是根據一個指定的範圍進行數據查詢
1:IN函數有助於減少OR條件的復合使用。
2:關於操作符IN和=的比較。
範例:查詢出雇員編號是7369、7566、7788、9999的雇員信息
利用關系運算符進行操作
select * from scott.emp where empno=7369 or empno=7566 or empno=7788 or empno=9999;
select * from scott.emp where empno IN (7369,7566,7788,9999);
select * from scott.emp where NOT IN (7369,7566,7788,9999); 相反
復習:
找出傭金高於薪金的百分之60的員工。
select * from scott.emp where comm>sal*0.6;
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
通用函數:(oracle自己特色)
1:處理Null;
Oracle中函數中除了字符函數、日期函數、數學函數、以及轉換函數等等,還有一些函數是通用函數,比如:NVL、NVL2,、NULLIF、COALESCE。
解釋 NVL函數
NVL(expr1,expr2)
如果expr1和expr2的數據類型一致,則:
如果expr1為空(null),那麽顯示expr2,
如果expr1的值不為空,則顯示expr1 。
範例:查找編號、姓名、工資、工資、傭金、如果傭金為空則顯示0,工資和傭金在乘以12.
select empno,ename,job,sal,comm,NVL(comm,0),(sal+comm)*12 income from scott.emp;
select empno,ename,job,sal,comm,nvl(comm,0),(sal+nvl(comm,0))*12 income from scott.emp;
2:多數值判斷;
含義解釋: decode(條件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
select empno,ename,job,DECODE(job,‘CLERK’,‘辦事員’,‘SALESMAN’,‘銷售’) from scott.emp;
select empno,ename,job,DECODE(job,‘CLERK’,‘辦事員’,‘SALESMAN’,‘銷售’,‘暫無此信息’) from scott.emp;
-----------------------------------------------------------------------------------------------------------------------------------
3.1:認識多表查詢
實際上所謂的多表查詢指的就是從多張數據表中取出數據並且顯示的一種操作。
select * from scott.emp,dept.emp 笛卡爾積存在的原因
實際:
SELECT * FROM scott.emp e, scott.dept d WHERE e.deptno=d.deptno;
-----------------------------------------------------------------------------------------------------------------------------------
3.2:查詢分析
範例1:查詢出每個雇員的編號,姓名、職位、基本工資、部門名稱、部門位置。
·確定要使用的數據表:
-:emp表:編號,姓名、職位、基本工資、
-:detp表:部門名稱、部門位置。
·確定已知的關聯字段:
-:雇員與部門:emp.deptno=dept.deptno
第一步:查詢出每個雇員的編號,姓名、職位、基本工資。
select e.empno,e.ename,e.job,e,sal from emp e;
第二步:查詢出每個雇員對應的部門信息;需要引入dept表(引入表的時候一定考慮有關聯),deptno字段關聯,所以利用where子句消除笛卡爾積。
select e.empno,e.ename,e.job,e.sal,d.dname,d.loc
from scott.emp e, scott.dept d
where e.deptno=d.deptno;
範例2:查詢出每個雇員的編號,姓名、職位、基本工資、工資等級。
select e.empno,e.ename,e.job,e.sal,s.grade
from scott.emp e,scott.salgrade s
where e.sal BETWEEN s.losal and s.hisal;
範例3:查詢出每個雇員的編號,姓名、職位、基本工資、部門名稱、工資等級。
確定所需要的數據表:
-:emp表:編號,姓名、職位、基本工資、
-:detp表:部門名稱、
-:salgrade表:工資等級
確定已知的關聯字段:
-:雇員與部門:emp.deptno-dept.deptno
-:雇員與工資等級;emp.sal BETWEEN salgrade.losal and salgrade.hisal
第一步:select e.empno,e.ename,e.job,e.sal
from emp e;
第二步:加入部門名稱、增加一張表就增加一條消除笛卡爾積。
select e.empno,e.ename,e.job,e.sal,d.dname
from emp e,dept d
where e.deptno=d.deptno;
第三步:加入工資等級信息,與原始的
select e.empno,e.ename,e.job,e.sal,d.dname,s.grade
from emp e,dept d,salgrade s
where e.deptno=d.deptno and e.sal between s.losal and s.hisal;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
表的連接:
內連接:
笛卡爾積就屬於內連接。只有滿足條件的情況下才會顯示。
外連接:
分為三種:左外連接,右外連接、全外連接
為了更好的觀察到連接的區別,現在已經在scott.dept表中提供了一個沒有雇員的部門(40部門),同時現在在scott.emp表中增加一個沒有部門的雇員。
insert into scott.emp (empno,ename,deptno) values(899,‘hello’,null);
可查看 select * from scott.emp;
觀察一:內連接實現效果
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno=d.deptno;
觀察二:使用左外連接;希望所有的雇員信息都顯示出來,即便沒有部門
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno=d.deptno(+);
觀察三:使用右外連接,將所有的部門信息顯示出來;
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno;
內連接指的就是滿足關聯條件的數據出現,不滿足的不出現,外連接就是指定一張數據表中的全部內容都顯示,但是沒有對應的其他表數據,內容為null。
在oracle裏面使用了‘(+)‘,來控制連接方式
·:左外連接:關聯字段1=關聯字段2(+);
·:右外連接:關聯字段1(+)=關聯字段2;
一般使用內連接,當你發現數據不全的時候可以考慮使用外連接;
範例:查詢每個雇員的編號、姓名、職位、領導姓名、領導職位; 自身關聯
確定所需要的數據表:
scott.emp表:(雇員信息):編號、姓名、職位
scott.emp表:(領導信息):領導姓名、領導職位
確定已知的關聯字段
雇員和領導:scott.mgr=memp.empno
第一步:查詢scott.emp表中的編號、姓名、職位。
select e.empno,e.ename,e.job
from scott.emp e;
第二步:加入領導信息,需要引入自身關聯,標出笛卡爾積
select e.empno,e.ename,e.job,m.ename,m.job
from scott.emp e,scott.emp m
where e.mgr=m.empno;
第三部:發現emp表雇員信息,數據不完整。如何想全部顯示則使用外連接
select e.empno,e.ename,e.job,m.ename,m.job
from scott.emp e,scott.emp m
where e.mgr=m.empnp(+);
-----------------------------------------------------------------------------------------------------------------------------------
SQL:1999語法定義
-----------------------------------------------------------------------------------------------------------------------------------
數據集合操作
UNION (無重並集):當執行UNION 時,自動去掉結果集中的重復行,並以第一列的結果進行升序排序。
範例:UNION 操作
select * from scott.emp
UNION
select * from scott.emp where deptno=10;
此時的查詢結果已經連接在一起了,但是UNION的處理過程是屬於取消重復元素;
範例2:UNION ALL 操作
UNION ALL (有重並集):不去掉重復行,並且不對結果集進行排序。
select * from scott.emp
UNION ALL
select * from scott.emp where deptno=10;
範例:驗證INTERSECT操作
INTERSECT(交集):取兩個結果集的交集,並且以第一列的結果進行升序排列。
select * from scott.emp
INTERSECT
select * from scott.emp where deptno=10;
範例:驗證差集
MINUS (差集):只顯示在第一個集合中存在,在第二個集合中不存在的數據。並且以第一列的結果進行升序排序。
select * from scott.emp
MINUS
select * from scott.emp where deptno=10;
7782 7839 7934
-----------------------------------------------------------------------------------------------------------------------------------
第五章:分組統計查詢:
5-1:統計函數:(分組函數)
常用的函數:
·:統計個數:COUNT(),根據表中的實際數據量返回結果;
·:求和:SUM(),是針對於數字的統計,求和
·:平均值:AVG(),各種數據類型都支持
·:最大值:MAX(),各種數據類型都支持
·:最小值:MIN(),求出最小值
範例:驗證各個函數:
select count(*) 人數,AVG(sal)員工平均工資,SUM(sal)每月總支出,
max(sal) 最高工資,min(sal)最低工資
from scott.emp;
範例:統計出公司的平均雇用年限
select avg(months_between(sysdate,hiredate)/12) from scott.emp;
範例:求出最早和最晚的雇傭日期
select max(hiredate)最晚,min(hiredate)最早 from scott.emp;
以上的幾個操作函數,在表中沒有數據的時候,只有CIUNT()函數會返回結果,其他都是NULL;
範例:統計bonus表
select count(*) 人數,AVG(sal)員工平均工資,SUM(sal)每月總支出,
max(sal) 最高工資,min(sal)最低工資
from bonus;
實際上針對於count()函數有三種使用形式;
·count(*):可以準確的說返回表中的全部記錄數;
·count(字段):統計不為null的所有數據量;
·connt(DISTINCT 字段);消除重復之後的結果;
範例:統計查詢一
select count(*),count(empno),count(comm) from scott.emp;
統計查詢二:
select count (DISTINCT job) from scott.emp;
5-2:分組統計
範例:根據部門編號分組、查詢出每個部門的編號、人數、平均工資。
select count(deptno) 編號,count(*),Avg(sal)
from scott.emp
group by deptno;
範例:根據職位分組,統計出每個職位的人數,最低工資與最高工資。
select job,count(*),min(sal),MAX(sal)
from scott.emp
group by job;
5-3:多表查詢與分組統計
範例:查詢出每個部門的名稱、部門人數、平均工資。
確定要使用的數據表
dept表:部門名稱
emp表:統計數據
確定已知的關聯字段
雇員與部門:scott.emp.deptno=scott.dept.deptno
第一步:換個思路,查詢出每個部門的名稱,雇員編號(count(empno))、基本工資(AVG(sal))
select d.ename,e.empno,e.sal
from scott.emp e,scott.emp d
where e.deptno=d.deptno;
第二步:
select d.ename,count(e.empno),AVG(e.sal)
from scott.emp e,scott.emp d
where e.deptno=d.deptno
group by d.ename;
第三部:外連接
select d.dname,count(e.empno),AVG(e.sal)
from scott.emp e,scott.emp d
where e.deptno(+)=d.deptno
group by d.ename;
範例:查詢每個部門的編號、名稱、位置、部門人數、平均工資;
確定要使用的數據表
dept表:編號、名稱、位置
emp表:統計信息
確定已知的關聯字段
雇員與部門:scott.emp.deptno=scott.dept.deptno
select d.deptno,d.dname,d.loc,e.empno,e.sal
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno;
第二步:此時發現有三個列(dept表)同事發生著重復,呢麽就可以進行多字段分組。
select d.deptno,d.dname,d.loc,count(e.empno),avg(e.sal)
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno
group by d.deptno,d.dname,d.loc;
5-4: HAVING子句
現在要求查詢出每個職位的名稱,職位的平均工資,但是要求顯示的職位的平均工資高於2000。
即:按照職位先進行分組,同時統計出每個職位的平均工資
隨後要求直顯示哪些平均工資高於2000的職位信息
select job,avg(sal)
from scott.emp;
group by job
having avg(sal)>2000
5-5:分組案例總結
範例:顯示所有非銷售人員的工作名稱以及從事同一工作雇員的月工資總和,並且要求滿足從事同一工作雇員的月工資的合計大於5000,顯示的結果按照月工資的合計升序排列;
第一步:查詢所以人非銷售人員的信息。
select *
from scott.emp
where job<>‘SALESMAN’;
第二步:按照職位進行分組,而後求出工資的總支出:
select job,SUM(sal)
from scott.emp
where job<>‘SALESMAN’
group by job;
第三部:分組後的數據進行再次篩選,使用HAVING語句
select job,SUM(sal)
from scott.emp
where job<>‘SALESMAN’
group by job
having sum(sal)>5000;
第四步:按照月工資的合計升序排列;使用order by
select job,SUM(sal) sum
from scoot.emp
where job<>‘SALESMAN’
group by job
having sum(sal)>5000
order by sum;
範例二:查詢出所有領取傭金的雇員的人數,平均工資。
select ’領取傭金‘ info ,count(*), avg(sal)
from scott.emp
where comm is not null
nuion
select ‘不領取傭金‘ info, count(*),avg(sal)
from scott.emp
where comm is null;
---------------------------------------------------------------------------------------------------------------------
6、子查詢:
6-1:子查詢簡介
6-2:
select * from scott.emp
where sal=(select MIN(sal) from scott.emp);
範例:查找出公司雇傭最早的雇員;
select min(hiredate) from scott.emp
以上查詢會返回單行單列的數據,所有可以直接在where語句中使用.
select * from scott.emp
where hiredate=(select min(hiredate) from scott.emp);
6.1.2、子查詢返回單行多列;
範例:查詢出與scott工資相同,職位相同的所有雇員信息。
select * from scott.emp where (sal,job)=(select sal,job from scott.emp where ename=‘SCOTT‘);
6.1.3 子查詢返回多行單列(重點)
在where字句裏面提供有主要的三個運算符:IN、ANY、ALL。
1:IN操作;
IN操作指的是內容可以在指定的範圍之中存在,
1.1:select sal from scott.emp where job=‘MANAGER’;
2975
2850
2450
1.2:select * from scott.emp
WHERE (sal,job)=(
select sal,job FROM scott.emp where ename=‘SCOTT‘);
多行單列就相當於給出了一個查詢範圍;
對於IN操作還可以使用not IN 進行;
select * from scott.emp
where sal NOT IN (select sal from scott.emp where job=‘MANAGER’;
2:ANY操作實際上有三種語法:
1:=ANY:功能上與IN完全是沒有任何區別;
select * from scott.emp
where sal =ANY (select sal from scott.emp where job=‘MANAGER’;
2:>ANY:比子查詢返回的最小的內容要大
select * from scott.emp
where sal >ANY (select sal from scott.emp where job=‘MANAGER’;
3:<ANY:比子查詢返回的最大的值要小
select * from scott.emp
where sal <ANY (select sal from scott.emp where job=‘MANAGER’;
3:ALL操作
ALL兩種操作
1:>ALL: 比子查詢返回的最大值要大
select * from scott.emp
where sal >ALL (select * from scott.emp where job=‘MANAGER’;
2:<ALL: 比子查詢的返回最小的值要小
select * from scott.emp
where sal <ALL (select * from scott.emp where job=‘MANAGER’;
4:EXISTS()判斷
範例:觀察exists()操作
select * from scott.emp
where exists(select * from scott.emp where deptno=99);
因為此時的查詢沒有返回任何的數據行買,所以exists()就認為數據不存在,外部查詢無法查詢出我內容。
範例:觀察exists()操作
select * from scott.emp
where exists(select * from scott.emp where empno=7839);
範例:觀察exists()操作
select * from scott.emp
where exists (select ‘hello’ from dual where 1=1);
範例:使用not exists()
select * from scott.emp
where not exists (select ‘hello’ from dual where 1=2);
6-3:使用HAVING字句查詢;
範例:要求統計出高於公司平均工資的部門編號、平均工資、部門人數。
第一步:根據部門編號分組,統計出每個部門編號的平均工資、部門人數。
select deptno,count(*),avg(sal)
from scott.emp
group by deptno;
第二步:如果要想知道哪些部門的工資高於公司的平均工資,則應該scott.emp表統計查詢
select avg(sal) from scott.emp;
第三步:統計函數
select deptno,count(*),avg(sal)
from scott.emp
group by deptno
having avg(sal)>(select avg(sal) from scott.emp);
6-4:select 子句使用子查詢
首先需要明確的是,這樣的操作意義不大,而且性能不高;
範例:查詢每個雇員的編號,姓名,職位,部門名稱;
select e.empno,e.ename,e.job,d.dname
from scott.emp e,soctt.emp d
where e.deptno=d.deptno;
6-5:FROM字句使用子查詢(重點)
為了解釋這種查詢的作用,下面做一個簡單的查詢;
select d.deptno,d.dname,d.loc,scott
總結: