SQL表连接与表设计

表连接与表设计

主要内容

  1. 表连接
  2. 表设计
  3. DDL

第一节 92 表连接

当我们获取的数据不是来自于同一张表而是来自于多张表时就需要使用到表连接
select * from emp;
select * from dept;
注意:同名列 非* 必须区分数据源 、关系列、 过滤条件、字段

1. 笛卡尔积
–非
必须区分 使用表名 或别名.区分
*

select * from emp , dept;
select ename , dname from emp , dept;
select ename, dname, e.deptno from emp e, dept d;

2. 等值连接(在笛卡尔积基础上 取条件列相同的值)

--查询员工姓名,工资及等级
--900 属于哪个等级
select grade from salgrade where 900 >losal and 900<hisal;
select grade from salgrade where 900 between losal and
hisal;
--查询员工姓名,工资及等级
-- 数据源: emp e, salgrade s
-- 字段: ename, grade, sal
-- sal between losal and hisal
select ename, grade, sal from salgrade s, emp e where sal
between losal and hisal;

4. 自连接: 特殊的等值连接 (来自于同一张表)

--找出 存在上级的员工姓名 及上级名称
-- 数据来源: emp e, emp m
-- 字段: e.ename, m.ename
-- 条件: e.mgr=m.empno
select e.ename, m.ename from emp e, emp m where
e.mgr=m.empno;

5. 外连接

--找出 所有的员工姓名 及上级名称
--找出 所有部门的员工数 及部门名称
select dname, nu from dept d, (select count(1) nu, deptno from emp
group by deptno) e
where d.deptno(+)=e.deptno;

看+和, 主表在,的左边就叫左外连接 主表在,的右边叫右连接

第二节 99 连接

 交叉连接 cross join —>笛卡尔积
 自然连接(主外键、同名列) natural join -->等值连接
 join using 连接(同名列) -->等值连接
 [inner]join on 连接 -->等值连接 非等值 自连接 (解决一切) 关系列必须区分
 left|right [outer] join on|using -->外连接
 full join on|using -->全连接 满足直接匹配,不满足 相互补充 null ,确保 所有表的记录 都至少出现一次

  1. 交叉连接
select * from emp cross join dept;
  1. 自然连接
select * from emp natural join dept;
--在指定列过程中同名列归共同所有(*除外)
select deptno,e.ename,d.dname from emp e natural join dept d;
  1. using 连接
select deptno,e.ename,d.dname from emp e join dept d using(deptno);
  1. on 连接
-- natrual 等值
select ename, dname
from emp
natural join dept
where deptno = 30;
--using
select ename, dname from emp join dept using (deptno) where deptno =
30;
--on
select ename, dname
from emp
join dept
on emp.deptno = dept.deptno 
where emp.deptno = 30;
on 非等值连接 、自连接
--部门编号为 30 的员工名称 工资等级
select ename, grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
where deptno=30;
--部门编号为 30 的员工名称 上级名称
select e.ename,m.ename mname from emp e join emp m
on e.mgr =m.empno where e.deptno =30;
--部门编号为 30 的员工 员工名称 部门名称 工资等级 上级名称
select e.ename, dname, grade, m.ename mname
from emp e
join dept d
on e.deptno = d.deptno
join salgrade s
on e.sal between s.losal and s.hisal
join emp m
on e.mgr = m.empno
where e.deptno = 30;
  1. 外连接
--所有部门的 部门名称,员工数
--左外
select dname, n
from dept d
left outer join (select deptno, count(1) n from emp group by
deptno) i
on d.deptno = i.deptno;
select dname, n
from dept d
left outer join (select deptno, count(1) n from emp group by
deptno) i
using (deptno);
--右外
select dname, n
from (select deptno, count(1) n from emp group by deptno) i
right outer join dept d
on d.deptno = i.deptno;
  1. 全连接
select *
from (select 1 no, 'a' "name"
from dual
union
select 2 no, 'b' "name" from dual) a
full join (select 1 no, 'c' "name"
from dual
union
select 3 no, 'd' "name" from dual) b
on a.no=b.no;
select *
from (select 1 no, 'a' "name"
from dual
union
select 2 no, 'b' "name" from dual) a
full join (select 1 no, 'c' "name"
from dual
union
select 3 no, 'd' "name" from dual) b
using(no);

第三节 试图和索引

1. 视图
视图:建立在表|结果集|视图上的虚拟表,有以下作用
1、简化:select 查询语句
2、重用:封装 select 语句 命名
3、隐藏:内部细节
4、区分:相同数据不同查询
不是所有的用户都有创建视图的权限
1、前提: create view -->组 connect resource dba
2、授权: -->sqlplus /nolog
a)、sys 登录 conn sys/123456@orcl as sysdba
b)、授权: grant dba to scott;
回收: revoke dba from scott;
c)、重新登录
create or replace view 视图名 as select 语句 [with read only];
要求:所有列必须存在名称。
对视图的删除不会删除原有表的数据
drop view 视图名;

求部门经理人中平均薪水最低的部门名称

--1)、部门经理人 -->mgr
create or replace view vw_emp_mgr as select distinct mgr from emp
where mgr is not null with read only;
--2)、部门经理人的薪水
create or replace view vw_emp_mgr_sal as
select *
from emp
where empno in (select mgr from vw_emp_mgr) with read only;
--3)、 按部门平均
create or replace view vw_emp_sal_group as select deptno,avg(sal)
avgsal from vw_emp_mgr_sal group by deptno with read only;
--4)、过滤组
--找出最低的 平均薪水
1)、 使用第三个视图
select min(avgsal) from vw_emp_sal_group
2)、使用第二个视图
select min(avg(sal)) minsal from vw_emp_mgr_sal group by deptno;
--获取部门编号及平均薪水
select *
from vw_emp_sal_group
where avgsal =
(select min(avg(sal)) minsal from vw_emp_mgr_sal group by
deptno);
--部门名称
select dname
from vw_emp_sal_group vw, dept d
where vw.deptno = d.deptno
and avgsal =
(select min(avg(sal)) minsal from vw_emp_mgr_sal group by
deptno);

2. 索引(了解)
 索引是数据库对象之一,用于加快数据的检索,类似于书籍的索引。在数据库中索引可
以减少数据库程序查询结果时需要读取的数据量,类似于在书籍中我们利用索引可以不
用翻阅整本书即可找到想要的信息。
 索引是建立在表上的可选对象;索引的关键在于通过一组排序后的索引键来取代默认的
全表扫描检索方式,从而提高检索效率
 索引在逻辑上和物理上都与相关的表和数据无关,当创建或者删除一个索引时,不会影
响基本的表;
 索引一旦建立,在表上进行 DML 操作时(例如在执行插入、修改或者删除相关操作
时),oracle 会自动管理索引,索引删除,不会对表产生影响
 索引对用户是透明的,无论表上是否有索引,sql 语句的用法不变
 oracle 创建主键时会自动在该列上创建索引
索引: 提高查询速度的一种手段 -->目录
1、唯一性较好字段适合建立索引
2、大数据量才有效果
3、主键|唯一: 唯一索引
create index 索引名 on 表名 (字段列表…)
drop index 索引名
create index idx_emp on emp(sal,ename);
drop index idx_emp;
select * from emp order by sal,ename;

第四节 表设计

1. 设计表
设计表首先应该按需遵循三范式
1、确定表名 2、确定字段名 类型 +约束(主键 外键 非空 默 检查认 唯一)
主键: 唯一标识一条记录(唯一并且非空)
唯一: 唯一
非空:不能为空
默认: 当没给值时使用给定一个默认值
外键:参考其他表(自己)的某个(某些)字段
检查:自定义的规则
2. 创建表(不加约束)
表名必须唯一,如果存在 ,必须删除

  1. 创建新表
create table 表名(
字段名 类型(长度) 约束,
...其他字段....
..约束........
);
表名 tb_user
主键 userid
字段名 中文 类型 为空 默认值 其他说明
userid 流水号 number(5) 否 主键
username 用户名 varchar2(30) 否 长度在 4-20
userpwd 密码 varchar2(20) 否 长度在 4-18
age 年龄 number(3) 18 大于>=18
gender 性别 char(2) 男 男 or 女
email 邮箱 varchar2(30) 唯一
regtime 注册日期 date sysdate
create table tb_user(
userid number(5),
username varchar2(30),
userpwd varchar2(20),
age number(3) ,
gender char(2) ,
email varchar2(30),
regtime date
);
--加入注释
comment on table tb_user is '用户表';
comment on column tb_user.userid is '流水号,主键';
comment on column tb_user.username is '用户名';
comment on column tb_user.userpwd is '密码';
comment on column tb_user.age is '年龄';
comment on column tb_user.gender is '性别';
comment on column tb_user.email is '邮箱';
comment on column tb_user.regtime is '注册日期';
表名 tb_txt
主键 txtid
字段名 中文 类型 为空 默认值 其他说明
txtid 流水号 number(10) 否 主键
title 标题 varchar2(32) 否 长度在 4-30
txt 正文 varchar2(1024)
pubtime 发布时间 date sysdate
userid 发布人 number(5) 外键,参考 tb_user 的 userid 列
create table tb_txt(
txtid number(10),
title varchar2(32),
txt varchar2(1024),
pubtime date,
userid number(5)
);
--注释
comment on table tb_txt is '文章表';
comment on column tb_txt.txtid is '流水号,主键';
comment on column tb_txt.title is '标题';
comment on column tb_txt.txt is '正文';
comment on column tb_txt.pubtime is '发布时间';
comment on column tb_txt.userid is '发布人,外键,参考 tb_user 的 userid 列';
--删除 (先删除从表 再删除主表 ;同时删除约束)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
  1. 已有表中拷贝结构
create table 表名 as select 字段列表 from 已有表 where 1!=1;
--拷贝结构 emp
create table emp_his as select ename,sal from emp where 1!=1;
--拷贝结构 emp +数据
create table emp_his2 as select ename,sal from emp where sal>2000;
  1. 删除表
drop table 表名 cascade constraints
--删除表
drop table emp_his2 cascade constraints;
drop table emp_his cascade constraints;

第五节 创建表

1. 创建表(同时创建约束+默认名称)
这种在创建表的同时创建约束并使用默认约束名称的方式,后期不方便排错, 所以不
推荐使用。其主要的优点是简单。

--删除 (先删除从表 再删除主表 ;同时删除约束)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
表名 tb_user
主键 userid
字段名 中文 类型 为空 默认值 其他说明
userid 流水号 number(5) 否 主键
username 用户名 varchar2(30) 否 长度在 4-20
userpwd 密码 varchar2(20) 否 长度在 4-18
age 年龄 number(3) 18 大于>=18
gender 性别 char(2) 男 男 or 女
email 邮箱 varchar2(30) 唯一
regtime 注册日期 date sysdate
create table tb_user(
userid number(5) primary key,
username varchar2(30) check(length(username) between 4 and 20) not null ,
userpwd varchar2(20) not null check(length(userpwd) between 4 and 18),
age number(3) default(18) check(age>=18),
gender char(2) default('男') check(gender in('男','女')),
email varchar2(30) unique,
regtime date default(sysdate)
);
--加入注释
comment on table tb_user is '用户表';
comment on column tb_user.userid is '流水号,主键';
comment on column tb_user.username is '用户名';
comment on column tb_user.userpwd is '密码';
comment on column tb_user.age is '年龄';
comment on column tb_user.gender is '性别';
comment on column tb_user.email is '邮箱';
comment on column tb_user.regtime is '注册日期';
表名 tb_txt
主键 txtid
字段名 中文 类型 为空 默认值 其他说明
txtid 流水号 number(10) 否 主键
title 标题 varchar2(32) 否 长度在 4-30
txt 正文 varchar2(1024)
pubtime 发布时间 date sysdate
userid 发布人 number(5) 外键,参考 tb_user 的 userid 列
create table tb_txt(
txtid number(10) primary key,
title varchar2(32) not null check(length(title)>=4 and length(title)<=30),
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5) references tb_user(userid) on delete set null
);
--注释
comment on table tb_txt is '文章表';
comment on column tb_txt.txtid is '流水号,主键';
comment on column tb_txt.title is '标题';
comment on column tb_txt.txt is '正文';
comment on column tb_txt.pubtime is '发布时间';
comment on column tb_txt.userid is '发布人,外键,参考 tb_user 的 userid 列';
--删除 (先删除从表 再删除主表 ;同时删除约束)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;

2. 创建表(同时创建约束+指定名称)
创建表的同时创建约束并指定约束的名称,后期方便排错,推荐使用
推荐, 便于后期排错

--删除 (先删除从表 再删除主表 ;同时删除约束)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
表名 tb_user
主键 userid
字段名 中文 类型 为空 默认值 其他说明
userid 流水号 number(5) 否 主键
username 用户名 varchar2(30) 否 长度在 4-20
userpwd 密码 varchar2(20) 否 长度在 4-18
age 年龄 number(3) 18 大于>=18
gender 性别 char(2) 男 男 or 女
email 邮箱 varchar2(30) 唯一
regtime 注册日期 date sysdate
create table tb_user(
userid number(5),
username varchar2(30) ,
userpwd varchar2(20) ,
age number(3) ,
gender char(2) ,
email varchar2(30),
regtime date default(sysdate)
);
--追加约束
alter table tb_user add constraint pk_user_id primary key (userid);
alter table tb_user add constraint ck_user_name check(length(username)between 4 and 20) ;
alter table tb_user add constraint ck_user_pwd check(length(userpwd) between 4 and 18);
alter table tb_user add constraint ck_user_age check(age>=18);
alter table tb_user add constraint ck_user_gender check(gender in('男','女'));
alter table tb_user add constraint uq_user_email unique(email);
--非空与默认
alter table tb_user modify (username constraint nn_user_name not null);
alter table tb_user modify (userpwd constraint nn_user_pwd not null);
alter table tb_user modify (age default(18));
alter table tb_user modify (gender default('男'));
--加入注释
comment on table tb_user is '用户表';
comment on column tb_user.userid is '流水号,主键';
comment on column tb_user.username is '用户名';
comment on column tb_user.userpwd is '密码';
comment on column tb_user.age is '年龄';
comment on column tb_user.gender is '性别';
comment on column tb_user.email is '邮箱';
comment on column tb_user.regtime is '注册日期';
表名 tb_txt
主键 txtid
字段名 中文 类型 为空 默认值 其他说明
txtid 流水号 number(10) 否 主键
title 标题 varchar2(32) 否 长度在 4-30
txt 正文 varchar2(1024)
pubtime 发布时间 date sysdate
userid 发布人 number(5) 外键,参考 tb_user 的 userid 列
create table tb_txt(
txtid number(10),
title varchar2(32),
txt varchar2(1024),
pubtime date,
userid number(5)
);
--追加约束
alter table tb_txt add constraint pk_txt_id primary key(txtid);
alter table tb_txt add constraint ck_txt_id check(length(title)>=4 and length(title)<=30);
--三种级联删除规则
alter table tb_txt add constraint fk_txt_ref_user_id foreign key(userid) references tb_user(userid);
alter table tb_txt add constraint fk_txt_ref_user_id foreign key(userid) references tb_user(userid) 
on
delete cascade ;
alter table tb_txt add constraint fk_txt_ref_user_id foreign key(userid) references tb_user(userid) 
on
delete set null;
--注意非空 默认
alter table tb_txt modify (title constraint nn_txt_title not null) ;
alter table tb_txt modify (pubtime default(sysdate));
--注释
comment on table tb_txt is '文章表';
comment on column tb_txt.txtid is '流水号,主键';
comment on column tb_txt.title is '标题';
comment on column tb_txt.txt is '正文';
comment on column tb_txt.pubtime is '发布时间';
comment on column tb_txt.userid is '发布人,外键,参考 tb_user 的 userid 列';
--删除 (先删除从表 再删除主表 ;同时删除约束)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
--2、分组
select name,
min(decode(course, '语文', score)) 语文,
min(decode(course, '数学', score)) 数学,
min(decode(course, '英语', score)) 英语
from tb_student
group by name;

第六节 表的其他操作

1. 修改表结构

1、修改表名 :rename to
2、修改列名: alter table 表名 rename column to
3、修改类型: alter table 表名 modify(字段 类型) 4、修改约束: 先删除 后添加
5、添加列: alter table 表名 add 字段 类型
6、删除列:alter table 表名 drop column 字段
--修改表名
rename tb_txt to tb_txt_new;
--修改列名
alter table tb_txt_new rename column txtid to tid;
--修改类型
alter table tb_txt_new modify(tid varchar2(20));
--添加列
alter table tb_txt_new add col varchar2(30);
--删除列
alter table tb_txt_new drop column col;
select * from tb_txt_new;

2. 删除表
1、先删除从表 再删除主表
2、删除表的同时删除约束

drop table tb_txt_new cascade constraints;
drop table tb_user cascade constraints;

3. 截断数据
truncate: 截断所有的数据 ,如果截断的是主表,结构不能存在 外键关联
截断数据同时 从结构上检查

create table emp_his as select * from emp where 1=1;
select * from emp_his;
--截断所有的数据
truncate table emp_his;
--不能截断: truncate table dept;

4. 序列
使用工具|程序管理流水号,序列在创建时 没有与表关联 ,在操作数据时 与表关联
1) 创建

create sequence 序列名 start with 起始值 increment by 步进;

2) 使用

在操作数据 添加 更新 -->主键
1)、currval :当前值
2)、nextval:下个值
create sequence seq_tb_user start with 2 increment by 2;
drop sequence seq_tb_user;
select seq_tb_user.nextval from dual;
select seq_tb_user.currval from dual;

3) 删除

drop sequence 序列名
发布了22 篇原创文章 · 获赞 6 · 访问量 443

猜你喜欢

转载自blog.csdn.net/ffgyfgj/article/details/105520755
今日推荐