oracle的一些实例

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 运行脚本文件

  1. @d:1.sql
  2. 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章