Oracle SQL
多表查询
表连接(关联查寻):
如果多表查询时不加where 子句,也就是过滤条件或者是使用了无效的条件,就会产生两表之间记录的相互逐条匹配(组合),产生很多无效的结果(笛卡尔积)。
1、 等值连接
注意:当为表起了别名,就不能再使用表名.字段名。
例:select a.first_name,a.last_name,b.name
from s_emp a,s_dept b
where a.dept_id=b.id;
表连接时,当表与表之间有同名字段时,可以加上表名或表的别名,加以区分,使用时要
用表名.字段名或表别名.字段名(列名)。当表的字段名是唯一时,可以不用加上表名或表的别名。
2、非等值连接
可以使比较运算符,也可以使其他的除了'='的运算符
例:select e.ename, d.grade,e.sal
from emp e,salgrade d
where e.sal between d.losal and d.hisal;
3、自连接
用别名把一张表中的数据分成两部分,然后在使用条件过滤
例:select a.first_name ename,b.first_name cname
from s_emp a,s_emp b
where a.manager_id=b.id;
以上所提到的表连接,都叫做内连接,严格匹配两表的记录。
4、外连接
会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中
的所有记录都会显示,数据库会模拟出记录去和那些不匹配的记录匹配。
例:select a.first_name enamei,a.id,b.first_name cname,b.id
from s_emp a,s_emp b
where a.manager_id=b.id(+);
即用a表中的数据去匹配b表的,若b表中有null,系统模拟纪录与其匹配
注意:要把那一方的记录全部都显示出来,还有注意条件(+)跟在要全部选出的对端。
外连接的应用:列出哪个部门没有员工
select e.deptno,d.deptno
from emp e,dept d
where e.deptno(+)=d.deptno
and e.deptno is null;
二、组函数
group 组
group by 分组子句,按指定的分组规则分组,
这个group by 子句可以跟在select语句后或是having后面。
group by子句也会触发排序操作,会按分组字段排序。
例:select avg(salary) from s_emp group by dept_id;
注意:组函数可以处理一组数据,返回一个值。组函数会忽略空值。
avg(..)求平均值,sum(..)求和这两个函数的参数只能是number型的。
以下所提到的函数可以使用任意类型做参数。
count(..),用来统计记录数,可以使用排重命令。count(...)默认使用的是all。
max(..),min(..)求最大值和最小值,
count(*),统计表中记录数。
例:select max(b.name), avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.dept_id;
注意:只要写了group by 子句,
select 后就只能用group by 后的字段或者是组函数。
where 子句只能够过滤记录,放单行函数。
having 子句可以过滤组函数结果或是分组的信息,且写在group by 子句后。
例:
select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id
having sum(a.salary)>4000;
column 也可以定义有别名的列的格式。
column "别名" 格式定义
注意:要先过滤掉不需要的记录,然后再进行分组操作,提高效率。
三、子查询
子查询,就是可以嵌在任何的sql语句中的select语句。
在select 语句中嵌套子查询时,会先执行子查询。一般的会将子查询放在运算符的右边。
注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值),
还是多行运算符(范围,多值,in)。
配合使用子查询返回的结果必须符合运算符的用法。
例:
select first_name,title
from s_emp
where title=any(select title
from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
select first_name,title
from s_emp
where title in (select title from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
四、业务需求转换成可操作的表
一: 需求分析
二: 画E-R 图
三: 转换成表关系
四: 割接(新老系统交接)
五:
E-R 图属性:
* 为强制且非空属性
o 可选属性(可以有值也可以没有)
#* 表示此属性唯一且非空
实体关系:
数量关系:
多对一关系
一对多关系
一对一关系
多对多关系
第一范式,所有的属性都必须是单值,也就是属性只表示单一的意义。
(记录可以重复,没有任何限制)
第二范式,属性要求唯一且非空,(记录不可重复,但是数据可能会出现冗余)。
第三范式,非主属性只能依赖于主属性,不能依赖于其他非主属性。
(解决数据冗余问题)
六、约束
约束是针对表中的字段进行定义的。
primary key(主键约束PK)保证实体的完整性,保证记录的唯一
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键,只有
两个字段放在一起唯一标识记录,叫做联合主键。
foreign key(外建约束FK)保证引用的完整性,
注意:被引用的表(父表)必须先存在,现有父亲后有儿子
外键约束,外键的取值是受另外一张表中的主键或唯一值得约束,不能够取其他值,只能够
引用主键或唯一键的值,被引用的表,叫做parent table(父表),
引用方的表叫做child table(子表),
要想创建子表,就要先创建父表,后创建子表,
记录的插入也是如此,先父表后子表,
删除记录,要先删除子表记录,后删除父表记录,
要修改记录,如果要修改父表的记录要保证没有被子表引用。
要删表时,要先删子表,后删除父表。
unuque key(唯一键),值为唯一
index(索引)是数据库特有的一类对象,view(示图)
典型的一对多 (class对应多个学生)
student table class table
______________________________ _______________________
| id | name | address | class_id | | id | class_desc | class_num|
|(PK)|______|________|___(FK)__| |(pk) |________|_________|
一对一
student tabel shenfenzheng table
_____________________ ____________________________
| id | name | address| | s_id | shenfen_desc| shenfen_num |
|(PK)|______|________| |(PK,FK)|____________|___________|
多对多
Student Table Middle Table Class Table
---------------------- ----- ------------------------------- ----------------
| id | name | address| | s_id | shenfen_desc|shenfen_num | | kid | class name|
|(PK)|______|________| |(FK,FK)|____________|__________| | (PK)|__________|
|联合主键|
引用对方表的主键,当作本身的主键,所以这个表的主键,既是主键又是外建