子查詢
當(dāng)一步不能求解時(shí),可以使用子查詢;
分為:
單行的子查詢
多行子查詢
單行操作符對(duì)應(yīng)單行子查詢,多行操作符對(duì)應(yīng)多行子查詢
可以再主查詢的select ,from,where ,having 都可以放子查詢
不可以在主查詢的group by中放子查詢
在select中放子查詢時(shí),要求只能是單行子查詢
in:
any :
小于某集合中的任意一個(gè)值,就是小于集合中最大值
大于某集合中的任意一個(gè)值, 就是大于最小值
例:select *from emp where sal < any (select sal from emp where deptno=10)
all:
小于某集合中的所有值,就是小于集合中的最小值;
大于集合中的所有值,就是大于集合中的最大值;
例:select *from emp where sal < all (select sal from emp where deptno=10) order by sal asc
題:
1.查詢工資最低的員工信息
select *from emp where sal=(select min(sal) from emp );
2. 找到薪水大于本部門平均薪水的員工
select *from emp a1 where sal > (select avg(sal) from emp a2 where a1.deptno=a2.deptno)
查看每一個(gè)部門的平均工資:select deptno 部門編號(hào),avg(sal) 部門平均工資 from emp group by deptno
3.找到員工表中工資最高的前三名
在oracle中有一個(gè):
rownum,是一個(gè)偽列,表示查詢結(jié)果的行號(hào)
1. 一旦生成就不會(huì)變化(會(huì)先按沒有排序的時(shí)候生成rownum)
2.杜宇rownum ,只能使用<或=,不能使用>或>=與=
select rownum, empno,ename,sal
from(
select empno,ename,sal from emp order by sal desc
)
where rownum<4
思路: 因?yàn)閞ownum 一旦生成不能改變,所以先將sal排好序。
最后條件限制時(shí)才使用rownum;
1,函數(shù)
字符函數(shù):
lower 全部轉(zhuǎn)為小寫
upper 全部轉(zhuǎn)為大寫
initcap 首字母轉(zhuǎn)為大寫
-------
concat 連接兩個(gè)字符串
substr 在字符串str中從第m個(gè)位置開始取n個(gè)字符(位置從1開始)
length 求長度
instr 從字符串strA中找出str所在的位置(返回第找到的1個(gè),位置從1開始)
lpad 把字符串str補(bǔ)齊到n個(gè)長度,不足就在左邊加指定字符c;
如果str.length>n就取str的前n個(gè)字符
rpad 把字符串str補(bǔ)齊到n個(gè)長度,不足就在右邊加指定字符c;
如果str.length>n就取str的前n個(gè)字符(也是從前面?。?BR> trim 從str的兩端去掉字符,要是指定的字符時(shí)才去掉,使用方式特殊:
例:trim('a' from 'aaITCASTaa') 結(jié)果為 'ITCAST'
trim('C' from 'aaITCASTaa') 結(jié)果為 'aaITCASTaa'
注意:前面只能指定一個(gè)字符。
replace 例:replace('aaITCASTaa', 'a', '=') 結(jié)果為 '==ITCAST=='
數(shù)字函數(shù):
round 四舍五入,例 round('45.923', 2) 表示保存兩位小數(shù),保留的位數(shù)可以指定正、零、負(fù)數(shù)。
trunc 截?cái)啵岬艉竺娴臄?shù),保留的位數(shù)可以指定正、零、負(fù)數(shù)。
mod 求余,如 mod(12, 5) 結(jié)果為2
日期函數(shù):
日期可以相減,但不能相加,因?yàn)闆]有意義。
select sysdate-1 昨天, sysdate 今天, sysdate+1 明天 from dual;
select ename,(sysdate-hiredate) 天,(sysdate-hiredate)/7 星期, (sysdate-hiredate)/30 月,(sysdate-hiredate)/365 年
add_months
next_day 從某個(gè)日期算起,下一個(gè)出現(xiàn)該星期幾的日期是哪天: select next_day(sysdate,'星期三') from dual;
last_day 當(dāng)月的最后一天
round
trunc
轉(zhuǎn)換函數(shù):
隱式數(shù)據(jù)類型轉(zhuǎn)換 與 顯式數(shù)據(jù)類型轉(zhuǎn)換
to_char(date, format)
to_date(string [,format])
to_char(number, format)
to_number(string [,format]) 如: to_number('22') 或 to_number('$22', '$99')
空值處理函數(shù):
NVL (expr1, expr2)
可以使用的數(shù)據(jù)類型有日期、字符、數(shù)字
NVL2 (expr1, expr2, expr3)
expr1不為NULL,返回expr2;為NULL,就返回expr3( expr1 != null ? expr2 : expr3 )
條件表達(dá)式:
用于實(shí)現(xiàn) IF-THEN-ELSE 邏輯。
CASE 表達(dá)式:SQL99的語法,比較繁瑣。
DECODE 函數(shù):Oracle自己的語法,類似Java,比較簡潔。
例:
根據(jù)員工的職位漲工資:總裁1000 經(jīng)理800 其他400
PRESIDENT
MANAGER
函數(shù)嵌套:
嵌套函數(shù)的執(zhí)行順序是由內(nèi)到外。
=================================================
2,集合運(yùn)算
查詢屬于部門10與部門20的所有員工信息,還可以這樣查
select * from emp where deptno=10
加上(這里寫集合運(yùn)算符)
select * from emp where deptno=20;
這就是集合運(yùn)算。
并集:
UNION 集合a + b的結(jié)果,沒有重復(fù)記錄。
UNION ALL 集合a + b的結(jié)果,保留所有重復(fù)的記錄。(用的比較少)
例:查詢屬于部門10與部門20的所有員工信息。
例:查詢工資在500~1500或在1000~2000范圍的員工信息(這是兩個(gè)工資級(jí)別)。
交集
Intersect 既屬于集合a又屬于集合b的記錄。
例:查詢工資在500~1500又在1000~2000范圍的員工信息(這是兩個(gè)工資級(jí)別)。
差集
Minus 集合a - b的結(jié)果,即從a中去除所有屬于集合b的元素,注意a-b與b-a的結(jié)果是不一樣的。
例:查詢屬于500~1500但不屬于1000~2000范圍的員工信息。
注意:
1,Select語句中參數(shù)類型和個(gè)數(shù)要一致
如果不一致,需要想辦法補(bǔ)齊。
例如要補(bǔ)個(gè)字符串,不能寫個(gè)'a'、'b'等,要不影響結(jié)果,應(yīng)補(bǔ)一個(gè)null,還要指定類型。
如果是字符串,可以寫 to_char(null);
如果要補(bǔ)數(shù)字類型,則寫 to_number(null)
2,結(jié)果集采用第一個(gè)select的表頭作為表頭。
在第一個(gè)select上起別名才有用。
在后面的select上起別名就沒有用。
3,如果有order by子句
必須放到最后一句查詢語句后。
=================================================
3,多表查詢
類型:
1. 等值連接
2. 不等值連接
3. 外連接
4. 自連接
等值連接:
例:查詢員工信息,要求顯示員工的編號(hào),姓名,月薪和部門名稱
select e.empno,e.ename,e.sal,d.dname
from emp e,dept d
where e.deptno=d.deptno;
不等值連接:
例:查詢員工的工資級(jí)別:編號(hào) 姓名 月薪和級(jí)別
select e.empno,e.ename,e.sal,s.grade
from emp e,salgrade s
where e.sal between s.losal and s.hisal;
過渡用的例子:
按照部門統(tǒng)計(jì)員工的人數(shù),要求顯示:部門號(hào),部門名稱,員工人數(shù)
select d.deptno,d.dname,count(e.empno)
from emp e,dept d
where e.deptno=d.deptno
group by d.deptno,d.dname;
結(jié)果:
DEPTNO DNAME COUNT(E.EMPNO)
---------- -------------- --------------
10 ACCOUNTING 3
20 RESEARCH 5
30 SALES 6
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> select * from emp where deptno=40;
未選定行
期望效果:當(dāng)連接條件不成立時(shí),仍然希望在結(jié)果中包含某些不成立的記錄。這就要用到外連接。
外連接:
左外連接:where e.deptno=d.deptno 當(dāng)連接條件不成立時(shí),等號(hào)左邊所代表的表的信息仍然顯示
右外連接:where e.deptno=d.deptno 當(dāng)連接條件不成立時(shí),等號(hào)右邊所代表的表的信息仍然顯示
左外連接的寫法: where e.deptno=d.deptno(+)
右外連接的寫法: where e.deptno(+)=d.deptno
實(shí)現(xiàn)上面的效果:
select d.deptno,d.dname,count(e.empno)
from emp e,dept d
where e.deptno(+)=d.deptno
group by d.deptno,d.dname
order by 1;
自連接:利用表的別名,將同一張表視為多張表
例:查詢員工信息:xxx的老板是yyy
select e.ename||'的老板是'||b.ename
from emp e, emp b
where e.mgr=b.empno;
使用SQL99標(biāo)準(zhǔn)的連接查詢(JOIN..ON..)
內(nèi)連接
只返回滿足連接條件的數(shù)據(jù)(兩邊都有的才顯示)。
select e.*, d.*
from emp e
inner join dept d
on e.deptno=d.deptno
-- 也可以省略inner關(guān)鍵字。
左外連接
左邊有值才顯示。
select e.*, d.*
from emp e
left outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer關(guān)鍵字
右外連接
右邊邊有值才顯示。
select e.*, d.*
from emp e
right outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer關(guān)鍵字
滿外聯(lián)接
任一邊有值就會(huì)顯示。
select e.*, d.*
from emp e
full outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer關(guān)鍵字
交叉連接:
叉集,就是笛卡爾積
select e.*, d.*
from emp e
cross join dept d
-- 沒有連接條件
=================================================
4,處理數(shù)據(jù)(DML,增刪改)
DML,Data Manipulation Language,數(shù)據(jù)操作語言
插入數(shù)據(jù)(Insert into):
插入全部列
插入部分列
插入空值
使用 & 變量(創(chuàng)建腳本)
例:
SQL> insert into emp (empno, ename, sal) values (&empno, &ename, &sal)
SQL> insert into emp (empno, ename, sal) values (&empno, '&ename', &sal)
SQL> update emp set ename='&new_name' where empno=&empno
SQL> select empno,ename,&col from emp;
可以在命令行sqlplus或是iSQL*Plus中演示。
從其它表中拷貝數(shù)據(jù)
insert into mytable
select mycolums from ...
更新數(shù)據(jù)(Update)
刪除數(shù)據(jù)(Delete)
刪除所有的記錄:
Delete
Truncate