子查詢
當(dāng)一步不能求解時,,可以使用子查詢;
分為:
單行的子查詢
多行子查詢
單行操作符對應(yīng)單行子查詢,,多行操作符對應(yīng)多行子查詢
可以再主查詢的select ,from,,where ,,having 都可以放子查詢
不可以在主查詢的group by中放子查詢
在select中放子查詢時,要求只能是單行子查詢
in:
any :
小于某集合中的任意一個值,,就是小于集合中最大值
大于某集合中的任意一個值,, 就是大于最小值
例: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)
查看每一個部門的平均工資:select deptno 部門編號,avg(sal) 部門平均工資 from emp group by deptno
3.找到員工表中工資最高的前三名
在oracle中有一個:
rownum,是一個偽列,,表示查詢結(jié)果的行號
1. 一旦生成就不會變化(會先按沒有排序的時候生成rownum)
2.杜宇rownum ,,只能使用<或=,不能使用>或>=與=
select rownum, empno,ename,sal
from(
select empno,ename,sal from emp order by sal desc
)
where rownum<4
思路: 因為rownum 一旦生成不能改變,,所以先將sal排好序,。
最后條件限制時才使用rownum;
1,,函數(shù)
字符函數(shù):
lower 全部轉(zhuǎn)為小寫
upper 全部轉(zhuǎn)為大寫
initcap 首字母轉(zhuǎn)為大寫
-------
concat 連接兩個字符串
substr 在字符串str中從第m個位置開始取n個字符(位置從1開始)
length 求長度
instr 從字符串strA中找出str所在的位置(返回第找到的1個,,位置從1開始)
lpad 把字符串str補(bǔ)齊到n個長度,不足就在左邊加指定字符c,;
如果str.length>n就取str的前n個字符
rpad 把字符串str補(bǔ)齊到n個長度,,不足就在右邊加指定字符c;
如果str.length>n就取str的前n個字符(也是從前面?。?BR> trim 從str的兩端去掉字符,,要是指定的字符時才去掉,使用方式特殊:
例:trim('a' from 'aaITCASTaa') 結(jié)果為 'ITCAST'
trim('C' from 'aaITCASTaa') 結(jié)果為 'aaITCASTaa'
注意:前面只能指定一個字符,。
replace 例:replace('aaITCASTaa', 'a', '=') 結(jié)果為 '==ITCAST=='
數(shù)字函數(shù):
round 四舍五入,例 round('45.923', 2) 表示保存兩位小數(shù),,保留的位數(shù)可以指定正,、零、負(fù)數(shù),。
trunc 截斷,,舍掉后面的數(shù),保留的位數(shù)可以指定正,、零,、負(fù)數(shù)。
mod 求余,,如 mod(12, 5) 結(jié)果為2
日期函數(shù):
日期可以相減,,但不能相加,因為沒有意義,。
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 從某個日期算起,,下一個出現(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范圍的員工信息(這是兩個工資級別),。
交集
Intersect 既屬于集合a又屬于集合b的記錄,。
例:查詢工資在500~1500又在1000~2000范圍的員工信息(這是兩個工資級別)。
差集
Minus 集合a - b的結(jié)果,,即從a中去除所有屬于集合b的元素,,注意a-b與b-a的結(jié)果是不一樣的。
例:查詢屬于500~1500但不屬于1000~2000范圍的員工信息,。
注意:
1,,Select語句中參數(shù)類型和個數(shù)要一致
如果不一致,需要想辦法補(bǔ)齊,。
例如要補(bǔ)個字符串,,不能寫個'a'、'b'等,,要不影響結(jié)果,,應(yīng)補(bǔ)一個null,還要指定類型,。
如果是字符串,,可以寫 to_char(null);
如果要補(bǔ)數(shù)字類型,則寫 to_number(null)
2,,結(jié)果集采用第一個select的表頭作為表頭,。
在第一個select上起別名才有用。
在后面的select上起別名就沒有用,。
3,,如果有order by子句
必須放到最后一句查詢語句后。
=================================================
3,,多表查詢
類型:
1. 等值連接
2. 不等值連接
3. 外連接
4. 自連接
等值連接:
例:查詢員工信息,,要求顯示員工的編號,,姓名,月薪和部門名稱
select e.empno,e.ename,e.sal,d.dname
from emp e,dept d
where e.deptno=d.deptno;
不等值連接:
例:查詢員工的工資級別:編號 姓名 月薪和級別
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)計員工的人數(shù),,要求顯示:部門號,,部門名稱,員工人數(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)連接條件不成立時,,仍然希望在結(jié)果中包含某些不成立的記錄,。這就要用到外連接。
外連接:
左外連接:where e.deptno=d.deptno 當(dāng)連接條件不成立時,,等號左邊所代表的表的信息仍然顯示
右外連接:where e.deptno=d.deptno 當(dāng)連接條件不成立時,,等號右邊所代表的表的信息仍然顯示
左外連接的寫法: 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)接
任一邊有值就會顯示,。
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