文章目錄
1 找出stu表中年齡第三大的學生基本信息
select * from
(select stu.sno 學號, stu.sname 姓名,stu.sage 年齡,
stu.sbirth 出生年月,stu.sdept 所在班級,
dense_rank() over (order by sage desc) rank from stu)
where rank =3
先對sage的進行降序排列後以rank值的方式對stu表中所有記錄排序,年齡最大記錄的rank值爲1,次之爲2;
dense_rank()
:
- 聚合函數
- 根據order by子句表達式的值,從查詢的每一行,計算它們與其他行的相對位置;
- 生成的序列從1開始,往後累加 ;
- 每次order by 表達式的值發生變化,該序列也隨之增加
2 查找列存在重複值的記錄
select * from stu s
where s.sdept in( select s.sdept
from stu s
group by s.sdept having count(*) > 1)
group by s.sdept having count(*) > 1
所在班級(s.sdept)列分組顯示的行數大於1
判斷某列是否存在重複值,使用having字句實現,判斷其count值是否大於1 即可。
3 只保留一行列存在重複值的記錄
delete from stu
where
#查找出重複值記錄
sdept in (
select sdept from stu
group by sdept having count(*) >1)
and
#找出班級列重複值記錄的rowid值,非最小rowid
rowid not in (
select min(rowid) from stu group by sdept having count(*) >1);
rowid的大小根據其寫入數據表的順序排列,先寫入的rowid值更小;
因此最終保留的2行存在重複值的記錄都是先寫入的記錄。
4 創建腳本文件
在SQL的最後一條語句中,不要以“;”代替“/”符號,否則運行報錯。
update stu set sage=sage+1 where sdept='12計算機’ /
select stu.sno 學號,stu.sname 姓名,stu.sage 年齡
from stu
order by sdept
/
5 運行腳本文件
- @d:1.sql
- start d:1.sql
6 提取表中的[N,M]條語句
select sno 學號,sname 姓名
from
(select rownum rn,t.* from stu t where rownum <= 4)
where s.rn>=2
/
由於rownum是僞列(根據查詢的數據後生成的,只能=,<,<=),不能用>=2來實現;
上述代碼首先通過子查詢找出stu表中前4行記錄,再在父查詢中將僞列值小於2的排除;
也可用減法集合運算實現,即將兩個select獲得的結果進行劍法運算。
7 快速編譯所有視圖。
spool d:1.sql
select 'alter view '||tname ||' compile;'
from tab
/
8 創建編號自動增加的列
alter table stu add sid varchar2(10);
create sequence sid_seq
increment by 1
start with 9
maxvalue 9999
nocache
nocycle
/
9 更新數據前先保存舊值
create or replace trigger tri_update
before update
on stu
for each row
begin
insert into del_emp
values(:old.sno,:old.sname,:old.sgentle);
end;
/
將數據保存在另一個臨時表del_tmp中,可用create del_tmp as select sno,sname,sgentle from stu where 1=2
複製表stu結構。
10 設置多條記錄具有相同值
update stu set (sgentle,sage,sdept)=
(select sgentle,sage,sdept from stu where sno='12001')
where sno='12008'
/
11 列值爲NULL情形的處理
update stu set sage = nvl(sage,0) +1
/
nvl(sage,0):當sage爲空時,用0代替
create or replace procedure emp_proc_select(v_empno number)
as
myename varchar2(20);
begin
select ename into myename from myemp where empno=v_empno;
dbms_output.put_line('myename:'||myename);
exception
when no_data_found then
dbms_output.put_line('沒有數據');
end;
/
12 通過having子句查詢
與where的差別:
- where是在分組前對每一行進行過濾的。
- having是對查詢出結果集分組(
group by
)後的結果進行過濾。
- WHERE 不能放在GROUP BY 後面
- HAVING 是跟GROUP BY 連在一起用的,放在GROUP BY 後面,此時的作用相當於WHERE
- WHERE 後面的條件中不能有聚集函數,比如SUM(),AVG()等,而HAVING 可以
查詢每個部門工資低於1500的人數
SQL> select deptno 所在部門 ,count(deptno) 所在部門人數
2 from emp
3 group by deptno
4 having deptno in
5 ( select deptno from emp
6 where sal >1500 )
7 order by deptno
8 /
所在部門 所在部門人數
---------- ------------
10 3
20 3
30 6