Oracle基础知识(6-10)

ORACLE知识总结
第六章——子查询 与 第十章——视图
例:查询和SMITH同部门的员工的信息,但是不包括SMITH select * from employees where last_name <> ‘SMITH’
and department_id = (select department_id from employees where last_name =‘SMITH’);

注意事项:
——子查询必须要写在括号中;
——子查询可以用在where,having和from(内联视图)字句中;
——子查询要写在比较运算符的右端;
——子查询通常不需要排序
练习:查询和SMITH同部门但是工资高于SMITH的员工信息
select * from employees
where department_id = (select department_id from employees where last_name = ‘SMITH’)
and salary>(select salary from employees where last_name = ‘SMITH’);

一.子查询分类
1、单行子查询:子查询对的结果集是一行一列的情况,可以用单行比较运算符(=,>,<,<>…)
例:查询部门人数高于平均部门人数的部门编号和人数
select department_id,count() from employees group by department_id
having count(
)>(select avg(count(*)) from employees group by department_id);

2、多行子查询:子查询的结果集是多行一列的情况,比较运算符不能使用单行比较运算符,只能用in,any和all
例:查询employees中领导的员工信息
select * from employees where employee_id in (select manager_id from employees);

any代表任意的例:列>any(多行子查询);
1.>any:大于结果集中的任意一条记录即可,就是大于结果集中的最小值;
2.=any:等于结果集中的任意一条记录即可,就相当于in;
3. 例:查询30部门中工资比任意的20号部门员工工资高的员工信息
select * from employees where department_id = 30 and salary > any (select
salary from employees where department_id = 20); 《==》 等价于
select * from employees where department_id = 30 and salary > (select min(salary) from employees where department_id = 20)

all 代表所有的
1.> all : 大于结果集中所有的记录,就是大于结果集中的最大值;
2.= all : 没有意义;
3.< all : 小于结果集中所有的记录,就是小于结果集中的最小值;
例:查询10部门中工资比所有的20部门员工工资高的员工信息
select * from employees where department_id = 10 and salary >all (select salary from employees where department_id = 20); 《==》等价于
select * from employees where department_id = 10 and salary > (select max(salary) from employees where department_id = 20);
例:查询emp表中不是领导的员工信息
select * from employees where employeess_is not in (select manager_id from employees where manager_id is not null);
结果集为空的原因 1. 子查询的结果集中出现了空值

二. not in不忽略空值。
select * from emp where mgr <> null;
a not in (1, 2, null) – 等价于 a <> 1 and a <> 2 and a <> null;

三.多列子查询:子查询的结果集是多列的情况,主查询中也应该用多列与之相比较
例:查询employees表中各部门工资最高的员工信息 select * from employees where (department_id, salary) in
(select department_id, max(salary) from employees group by department_id) order by department_id;
例:查询employees表中和allen同部门且同领导的员工信息
select * from employees where department_id = (select department_id from employees where last_name = ‘allen’) and manager_id = (select manager from employees where last_name= ‘allen’); 《==》等价于
select * from employees where (department_id, manager) in (select department_id, manager from employees where last_name = ‘allen’);

四. 内联视图
视图 :就是虚表。首先视图是表,他就和表的访问方式一模一样。没有实体只有定义。
内联视图就是from子句中的子查询,就是一个命名的查询 把子查询放到from子句中,给他起个名字,这个名字一定要符合oracle对象的命名规则。
如果内联视图中出现的函数列或表达式列的话,一定要为这样的列起一个别名,就对应内联视图中列的列名
CREATE VIEW view_name AS subquery;

练习:创建一个20部门所有员工的视图emp_20
Create Or Replace View emp_20 As Select * From emp Where deptno = 20 With Read Only;

例:查询employees表中各部门工资最高的员工信息
select * from (select department_id,max(salary) maxsal from employees group by department_id) a,employees e
where a.department_id = e.department_id and e.salary = a.maxsal

例:查询employees表中和allen同部门且同领导的员工信息
select e.* from employees e,(select department_id,manager_id from employees where last_name = ‘allen’) a where e.department_id = a.department_id and e.manager_id = a.manager_id;

例:查询employees表中各部门工资最高的员工姓名,工资以及工资等级
select e.last_name,e.salary,s.grade_level from (select
department_id,max(salary) maxsal from employees group by department_id) a,employees e,job_grades s
where a.department_id = e.department_id and e.salary = a.maxsal and e.salary between s.lowest_sal and s.highest_sal;

select b.last_name,b.salary,b.grade_level
from(select e.last_name,e.department_id,e.salary,s.grade_level from employees e,job_grades s where e.salary between s.lowest_sal and s.highest_sal) b,
(select department_id,max(salary) maxsal from employees group by department_id) a
where b.department_id = a.department_id and b.salary = a.maxsal;

内联视图的列有哪些作用 1.作为最终的查询结果 2.作为连接条件
例:查询employees表中各部门工资最高的员工姓名,工资以及工资等级,部门名称
select b.last_name,b.salary,s.grade_level
from (select e.last_name,e.salary from (select department_id,max(salary) maxsal from employees group by department_id) a,
employees e where a.department_id = e.department_id and a.maxsal = e.salary) b, job_grades s where b.salary between s.lowest_sal and s.highest_sal;

select e.last_name,e.salary,b.grade_level from ( select a.department_id,a.maxsal,s.grade_level
from (select department_id,max(salary) maxsal from employees group by department_id) a,job_grades s
where a.maxsal between s.lowest_sal and s.highest_sal) b, employees e where b.department_id = e.department_id and e.salary = b.maxsal;

例:查询employees表中员工姓名,工资,工资等级以及部门名称,即使这个员工没有部门
select a.last_name,a.salary,a.grade_level,d.department_name from (select e.last_name,e.salary,e.department_id,s.grade_level from employees e,job_grades s where e.salary between s.lowest_sal and s.highest_sal) a, departments d
where a.department_id = d.department_id(+);
内联视图的重要应用——Top-N 问题查询由低到高或由高到低排在前N位的记录
例:查询employees表中工资由高到低排在前三位的员工信息
– oracle 伪列
– rownum : 每个select语句的结果集中都存在这样的伪列
– 它的作用是为结果集中的记录进行编号
select rownum, last_name, salary from employees where rownum < 4 order by salary desc;

注意1. rownum 编号在order by之前进行
select rownum r, a.last_name, a.salary from (select last_name, salary from employees order by salary desc) a where rownum < 4;

分页问题
例:查询employees表中工资由高到低排在4~6位的员工信息
注意2. rownum只能使用<或<=,不能使用>或>= ,如果用=进行比较,只能=1
-rownum在比较筛选的时候会动态的重新进行编号
select * from(select rownum r,a.last_name,a.salary from(select last_name, salary from employees order by salary desc)a where rownum< 7) b where b.r>3;

例:查询employees表中和smith入职时间最接近的员工信息
select rownum,a.last_name,a.hire_date from(select last_name,hire_date, abs(months_between(hire_date,(select hire_date from employees where last_name = ‘SMITH’)))mb from employees where last_name <> ‘SMITH’ order by mb) a where rownum = 1;

例:表 create table n (num number);
1.所有的数字不重复
2.有些数字是连续的,有些数字是不连续的
select num from n order by num;
例:查询employees表中每个部门中工资从高到低排在前三位的员工信息
select * from(select rank()over(partition by department_id order by salary desc)r,e.*from employees e) where r<4;

第七章——创建和管理表 与 第八章——数据处理
一.创建表 create table
例:创建一个表名为dept,列名有loc,department_id,department_name
create table dept(loc char(10),department_id number,department_name char(20));

二.数据类型
1、数字类型
number[(p[,s])]
p 表示数字的总长度s 表示小数位的长度

(2)、字符型
1、 可变长度的字符类型
varchar2(n)
n 表示字符的长度,n必须指定不能省略, n<4000
2、 固定长度的字符型
char[(n)]
n 表示字符的长度,n默认是1,n < 2000
3. 日期型
– date
– Rowid 伪列,唯一行地址
Select Rowid, last_name, salary From employees;

例:学生信息表,students
1、学号4位数字 (sno)
2、姓名可变的30个字符长度的字符型
3、生日日期型
4、身高 3位数字( stature)
5、班级编号 2位数字(class_code),默认值10
创建students表
create table students(sno Number(4),sname varchar2(30),birthday date,stature number(3),class_code number(2) default 10);
向students表中添加一条数据
insert into students values (1000, ‘张三’, to_date(‘1985-1-1’, ‘YYYY-MMDD’),
175, 20);
再查看students表
select *from students;

二.insert语句

  1. insert into 表名 [(列名列表)] values (值的列表);(可以插入一条数据)
    例:向dept表中插入新的部门,部门编号50,部门名称:培训部,部门地点:沈阳 insert into dept (loc,department_id,department_name)values(‘沈阳’,50,‘培训部’);
    insert into dept values(51, ‘培训部’, ‘沈阳’);
    例:向dept表中插入新的部门,部门编号60,部门名称:商用,部门地点为空
    insert into dept(loc,department_id,department_name)values (null, 60, ‘商用’);

也可以用两个连续的单引号来代替空值
insert into dept values (’’,61,‘商用’);
也可以在指定列名列表时,忽略空值列,如果这列没有设定默认值的话,那么它将会被插入空值
insert into dept (department_id,department_name) values (62, ‘商用’);

例:把你自己的信息插入到employees表中
插入日期的三种方式 使用sysdate插入当前系统日期 使用oracle默认的日期格式 ‘DD-MON-YYYY’ 使用to_date函数
insert into employees values(9999,‘Liujun’,null,7788, to_date(‘2011-4-21’,
’ DD-MON-YYYY '),20000,null,null);

批量插入 Insert Into 表名 [(列名列表)] 子查询;
create table employ as select * from employees where 1=2;
例:将employees表中10部门所有员工信息插入到employ表中;
insert into employ select * from employees where department_id = 10;

2.Update 语句
Update 表名 Set 列名1 = 表达式1 , 列名2 = 表达式2… [Where 条件];
限定了被更新的记录
例:给所有20号部门的员工涨工资100
update employ set salary = salary + 100 where department_id = 20;

练习:将你自己的领导设定为SCOTT,且和SCOTT同部门
update employ set
manager_id = (select employee_id from employ where last_name =
‘SCOTT’),department_id = (select department_id from employ where last_name
= ‘SCOTT’) Where employee_id = 9999;

例:将你自己的工资设定为30部门平均工资-100,并且截断到个位
update employ set salary = (select trunc(avg(salary)-100)from employ where department_id = 30)where employee_id = 9999;

3.delete 语句
Delete [From] 表名 [Where 条件] ;
限定删除那些记录 delete是删除表中记录,而不是删除表 为了消除歧义,通常情况下都不省略from关键字 Delete From employ;
例:删除本部门中比你自己工资高的员工记录
delete from employ where employee_id in(select e.employee_id from employ e,(select department_id,salary from employ where employee_id = 9999) a where e.department_id = a.department_id and e.salary > a.salary);

4.default值的用法
1.和插入空值相似
insert into students(sno, sname, birthday, stature) values ( 1001, ‘李四’, to_date(‘1986-6-1’, ‘YYYY-MM-DD’), 180);
2.直接使用default关键字
insert into students values (1002, ‘王五’, to_date(‘1985-1-1’, ‘YYYY-MMDD’), 175, default);
3.update中使用默认值
例:把张三的班级编号修改成该列的默认值
update students set class_code = default where sname = ‘张三’;

5.子查询建表
create table 表名[(列名列表)] as 子查询;
例:创建一个表student1将students表中的数据全部复制过来
create table student1 as select * from students;

例:创建一个表employ将employees表中的last_name,salary,年salary添加到 employ表中
create table employ(Name,salary,annual_salary)as select last_name,salary, salary*12 from employees;

6.修改表结构 Alter Table
1.向表中添加一列 Alter Table 表名 Add (列名 数据类型);
例:添加sex列,固定长度一位字符的字符型
alter table students add (sex char);
2.修改表中现有列的属性 Alter Table 表名 Modify (列名 要修改的属性值);
例:给sex列设定默认值’1’
alter table students modify (sex default ‘1’);
3.删除列
Alter Table 表名 Drop Column 列名;
Alter Table 表名 Drop (列名1, 列名2…);
4.删除表 Drop Table 表名;
5.截断表truncate table 表名; 删除表中所有数据。
truncate 和 delete的区别
1、truncate不能回滚, 而delete可以;
2、truncate只能删除所有数据,而delete可以删除部分数据;
3、truncate会释放存储空间,delete不会;
4、对于大数量的表,trunacate的效率要远远高于delete;
5、约束 用户在某个表的某个列上添加的一个限制条件,防止无效的数据添加到数据库中 or acle中的约束

第九章——约束
1、not null : 非空约束
2、unique: 唯一约束,允许空值
3、primary key: 主键约束——非空约束和唯一约束的总和
4、foreign key:外键约束——表A和表B的公共字段,如果是表A的主键或唯一键的话,那么它就是表B的外键

一. 列级的约束定义
Create Table country (country_code Char(2) Primary Key,country_name Varchar2(30),num Number Check(num > 0));

Create Table emp ( … deptno Number(2) References dept(deptno) – 列级的外键约束)

二. 表级的约束定义
Create Table table_name ( 列的定义, Constraint 约束名 Type(列名),Constraint 约束名 Type(列名)… )
Create Table country ( country_code Char(2), country_name Varchar2(30) , Constraint country_code_pk Primary Key(country_code), Constraint country_name_uk Unique(country_name), Constraint country_name_nn Not Null(country_name)
– 错误的,not null 没有表级的约束定义 );
Create Table emp ( … deptno Number(2), Constraint emp_deptno_fk Foreign Key (deptno) References dept(deptno) )

练习:创建一个班级表 class_table 班级编号 2位数字 (class_code),是该表的主键 班级名称 30位长度的可变长度字符类型(class_name),不可重复
Create Table class_table ( class_code Number(2) , class_name Varchar2(30) , Constraint class_table_code_pk Primary Key (class_code), Constraint class_table_name_uk Unique(class_name) );

1.为已有的表添加约束的语法
练习:向student表中的sno列添加主键约束
Alter Table student Add Constraint student_sno_pk Primary Key (sno);

2.删除约束
Alter Table student Drop Constraint student_class_code_fk;
Alter Table student Drop Primary Key;

练习:删除class_table的主键约束
Alter Table class_table Drop Primary Key Cascade;
Select * From user_constraints;

你可能感兴趣的:(Oracle)