数据库命令的深入学习

一.连表查询

​ 当要查询的数据来自于不同的表中,可以使用连表查询

1. 92语法

​ 表和表之间使用,连接
select 数据 from 数据来源1,数据来源2,数据来源3…
笛卡尔积 (对乘)

(1)内连接

(内部做满足条件显示不满足不显示)和外链接(有的表中的数据不满足条件也可以显示)
连接条件: where中定义连接条件 等值连接 非等值连接
注意:同名字段必须指明出处

select 数据 from 数据来源1,… where 行过滤条件|表连接条件 group by 分组字段… having 组过滤条件 order by 排序字段…;

–执行流程: from —> where --> group by —> having —> select —> order by

--等值连接:两个表的连接字段,不定义是同名字段或者主外键关系的,数据类型需要保持一致
--查询员工的信息和所在的部门信息
select * from emp, dept where emp.deptno = dept.deptno;
select * from emp e, dept d where e.deptno = d.deptno;
select * from emp , dept where emp.ename = dept.dname;

--select 数据 from 数据来源1,....  where 行过滤条件|表连接条件  group by 分组字段.. having 组过滤条件 order by 排序字段..;
--执行流程: from --- where--group by ---having ---select ---order by
--查询30部门的员工信息和所在部门信息
select empno,ename,d.deptno,dname from emp e,dept d where e.deptno = d.deptno and e.deptno!=30 order by e.deptno desc; --先连接后判断,相对效率较低,连接数据多
--先过滤后连接
--select * from (30部门员工信息) e,(30部门的部门信息) d;
select * from (select * from emp where deptno = 30) e,(select * from dept where deptno=30) d;

--非等值连接
--查询2500工资所在的等级信息
select * from salgrade;
select grade from salgrade where 2500 between losal and hisal;

--查询的所有的员工的信息以及对应的薪资等级
--数据:员工信息,薪资等级
--来源: emp,salgrade
--条件:sal between losal and hisal;
select * from emp,salgrade where emp.sal between losal and hisal;

--30部门的,薪资>1500的员工信息,所在的部门信息,工资等级信息
select *
  from emp e, dept d, salgrade s
 where e.deptno = d.deptno
   and sal between losal and hisal
   and e.deptno = 30
   and sal > 1500;
(2)外连接

左外连接右外连接

主表:主表中的数据无论是否满足条件都会显示

​ 主表在左边就是左连接,主表在右边就是右连接

--做表连接的时候,要满足连接条件才能显示,如果想要某张表中的数据无论是否满足条件都显示,可以使用外链接
--外连接:左外连接和有外连接接
--主表:主表中的数据无论是否满足条件都会显示
--查询所有员工信息以及上级经理人信息  员工表作为主表
--emp e1,emp e2  主表在左边就是左连接,主表在右边就是右连接
select * from emp e1,emp e2 where e1.mgr= e2.empno(+);  --左连接
select * from emp e2,emp e1 where e1.mgr= e2.empno(+);  --右连接

2. 99语法

select 数据 from 数据来源1 join 数据来源2;
笛卡尔积 (对乘) cross join

--select 数据 from 数据来源1 join 数据来源2; 
--笛卡尔积  对乘   cross join
select * from emp e cross join dept d; --99
select * from emp,dept;  --92

1)内连接

(inner) join inner默认可以不写

(1)自然连接

​ 自动做等值连接

​ 注意: 同名字段不要使用限定词

natural join 自动帮你做等值连接 同名字段|主外键关系

join using(字段) 指明对哪一个字段做等值连接

(2)等值连接
--(inner) join  内连接
--等值连接
--自动做等值连接
--注意: 同名字段不要使用限定词
--自然连接  natural join 自动帮你做等值连接  同名字段|主外键关系
  select empno,ename,deptno,dname from emp e  natural inner join dept d;
  --join using(字段) 指明对哪一个字段做等值连接
  select  empno,ename,deptno,dname from emp inner join dept using(deptno);
  
-- 数据来源1 join 数据来源2  on 连接条件(等值|非等值)  同名字段需要指明出处
select empno,ename,emp.deptno,dname from emp join dept on emp.deptno = dept.deptno;

--非等值连接
--员工信息和工资等级
select * from emp e inner join salgrade s on e.sal between losal and hisal;

select *
  from emp
  join dept
    on emp.deptno = dept.deptno
  join salgrade
    on sal between losal and hisal
 where emp.deptno = 30;
(3)外链接

外链接: left join | right join 左外链接|右外链接

全连接: 结果集 union 结果集

--外链接  left join  | right join
--主表
--所有员工信息和上级信息
select * from emp e1 left join emp e2 on e1.mgr = e2.empno;

--全连接 union
select 1 no, 'a' "name" from dual union select 2 no, 'b' "name" from dual;
select 1 no, 'c' "name" from dual union select 3 no, 'd' "name" from dual;
 
--内连接  满足条件显示
select *
  from (select 1 no, 'a' "name"
          from dual
        union
        select 2 no, 'b' "name"
          from dual) a
  join (select 1 no, 'c' "name"
          from dual
        union
        select 3 no, 'd' "name"
          from dual) b
    on a.no = b.no;
    
--左外链接 a表中的数据满不满足条件都显示  
select *
  from (select 1 no, 'a' "name"
          from dual
        union
        select 2 no, 'b' "name"
          from dual) a
  left join (select 1 no, 'c' "name"
          from dual
        union
        select 3 no, 'd' "name"
          from dual) b
    on a.no = b.no;
--右外链接 b表中的数据满不满足条件都显示  
select *
  from (select 1 no, 'a' "name"
          from dual
        union
        select 2 no, 'b' "name"
          from dual) a
  right join (select 1 no, 'c' "name"
          from dual
        union
        select 3 no, 'd' "name"
          from dual) b
    on a.no = b.no;

--全链接 a,b表中的数据满不满足条件都显示  
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;

3.视图

视图是虚拟表

操作视图其实数据还是在对应的表中,使用视图最大的好处可以简化select语句代码

不是所有的账号都有权限创建视图

1)授权

​ 1)切换到管理员账号sys

​ 2) grant dba to 账户名; 授权

​ 回收权限 revoke dba from 账号名;

2)创建视图

create or replace view 视图名 as select语句 [with read only];

--视图是虚拟表,操作视图其实数据还是在对应的表中,使用视图最大的好处可以简化select语句代码
--不是所有的账号都有权限创建视图
--需要授权  1)切换到管理员账号sys  2) grant dba to 账户名;授权   回收权限revoke dba from 账号名;
--创建视图
--create or replace view 视图名 as select语句 [with read only];
create or replace view vw_haha as select empno,ename,sal from emp where deptno=30 with read only;
--drop view 视图名; 删除视图
drop view vw_haha;
select * from vw_haha;

--update 表名 set 字段=值 [,....] where 过滤行记录;
update vw_haha set sal=200  where empno = 7499;

grant dba to SCOTT;
--对每个部门中所有经理人求平均薪资,查询平均薪资最低的部门的部门民称
--所有的经理人
select distinct mgr from emp where mgr is not null;
--创建视图存储所有的经理人
create or replace view vw_mgr as select distinct mgr from emp where mgr is not null with read only;
select * from vw_mgr;

--对所有的经理人进行分组,查到部门编号,经理人的平均薪资
select deptno, avg(sal)
  from emp
 where empno in (select distinct mgr from emp where mgr is not null)
 group by deptno;

--最低平均薪资
select min(avg(sal))
  from emp
 where empno in (select distinct mgr from emp where mgr is not null)
 group by deptno;

--判断哪一个部门的薪资与最低平均薪资相等,获取到这个部门的部门编号
select deptno
  from (select deptno, avg(sal) avg_sal
          from emp
         where empno in (select distinct mgr from emp where mgr is not null)
         group by deptno)
 where avg_sal =
       (select min(avg(sal))
          from emp
         where empno in (select distinct mgr from emp where mgr is not null)
         group by deptno);
--根据部门编号获取部门名称
select dname
  from dept
 where deptno =
       (select deptno
          from (select deptno, avg(sal) avg_sal
                  from emp
                 where empno in
                       (select distinct mgr from emp where mgr is not null)
                 group by deptno)
         where avg_sal =
               (select min(avg(sal))
                  from emp
                 where empno in
                       (select distinct mgr from emp where mgr is not null)
                 group by deptno));
--视图
select dname
  from dept
 where deptno = (select deptno
                   from (select deptno, avg(sal) avg_sal
                           from emp
                          where empno in (select * from vw_mgr)
                          group by deptno)
                  where avg_sal = (select min(avg(sal))
                                     from emp
                                    where empno in (select * from vw_mgr)
                                    group by deptno));

3)修改

update 表名 set 字段=值 [,…] where 过滤行记录;

4.索引

--索引
--是数据库的对象之一,是透明的,有没有索引,sql都一样
--大量的数据的查询,如果数据量比较小,如果不是大量做查询,二十大量的执行增删改的操作,反而会降低效率,因为需要维护索引
--字典的目录
select * from emp where sal>1500;

--create index 索引名 on表名 (字段列表...)
--drop index 索引名

5.表设计

​ 三范式的规范

​ 表的名称, 字段,类型,要求( 一对多|多对一(主外键) 多对多(中间表)

--DDL 定义语句    创建表 create 删除表drop  修改alter
--创建表
--create table 表名(
     --字段名 类型  约束,
     --字段名 类型  约束,
     -- 字段名 类型 ,
     --约束;
     --约束....
--)
--追加约束

--创建表,不添加约束
--学生表
create table sxt_student(
       sid number(5), --5为有效数字  (5,2) 5位有效数字其中2位是小数
       sname varchar2(4 char),  --默认字节数 如果想要指定字符个数 varchar2(4 char)
       sage number(3),
       gender char(3), --默认3个字节
       birthday date
)
--分析: 学堂  学生  老师  班级  定义表
--分析: 学生的id等字段应该不能重复等其他要求 解决办法: 1) 逻辑方面,代码层面上进行判断  2)为数据库中的表的字段添加约束要求

--创建表的同时添加约束  1)默认约束名  优点:简单  缺点:不便于后期维护
--学生表
create table sxt_student(
       --主键约束  (非空+唯一)
       sid number(5) primary key, 
       --非空约束 not null
       sname varchar2(4 char) not null, 
       --检查约束  check() 
       sage number(3) check(sage >=0 and sage<=150),
       --检查约束 '男' '女'
       gender char(3) check(gender in ('男','女')),
       --默认约束
       birthday date default(sysdate),
       --唯一约束  手机号不能重复
       phoneNum number(11) unique
)

--班级表
create table sxt_class(
       cid number(5) primary key,
       cname varchar2(15) not null
)

6.约束

创建表 和 添加约束

--先创建表,后续为这个表的什么字段添加约束
--创建表的同时添加约束
      --创建表 字段后直约束)
--表和表之间的关系   一对一接添加约束  1)默认的约束名     2)指定约束名
      --       字段定义完成之后,统一为不同的字段的添加约束
      
--创建表的同时添加约束  1)默认约束名  优点:简单  缺点:不便于后期维护

--创建表的同时添加约束  2)字段后添加指定约束名 3)字段声明后,表结构结束之前添加约束
create table sxt_student(
       --主键约束  (非空+唯一)
       sid number(5),      -- constraints pk_sxt_student_sid primary key, 
       --非空约束 not null
       sname varchar2(4 char) constraints sname_not_null not null, 
       --检查约束  check() 
       sage number(3) constraints ck_sage check(sage >=0 and sage<=150),
       --检查约束 '男' '女'
       gender char(3),
       --默认约束
       birthday date default(sysdate),
       --唯一约束  手机号不能重复
       phoneNum number(11),
       --外键约束  学生所在的班级
       cid number(5), --constraints fk_sxt_class_cid  references sxt_class(cid),--references sxt_class(cid),
       
       --添加约束 
       constraints pk_sxt_student_sid primary key(sid),
       --constraints ck_gender check(gender in ('男','女')),
       constraints un_phonenum unique(phoneNum),
       constraints fk_sxt_class_cid foreign key(cid) references sxt_class(cid) 
)
--表结构结束之后追加约束
alter table sxt_student add  constraints ck_gender check(gender in ('男','女'));
alter table sxt_student drop constraints ck_gender;

--加入注释
comment on table sxt_student is '学生表';
comment on column sxt_student.sid is '学生编号,主键';
comment on column sxt_student.sname is '学生姓名';

7. DDL 和 DML

--班级表   主表
create table sxt_class(
       cid number(5) primary key,
       cname varchar2(15) not null
)
--学生表  从表
create table sxt_student(
       --主键约束  (非空+唯一)
       sid number(5) primary key, 
       --非空约束 not null
       sname varchar2(4 char) constraints sname_not_null not null, 
       cid number(5),
       -- 添加外键约束的时候 on delete set null,当主表数据被删除时,从表引用这条数据的外键字段值为null
       constraints fk_sxt_class_cid foreign key(cid) references sxt_class(cid) on delete cascade      --on delete set null
)
--查询
select * from student;
select * from sxt_class;
--删除表
drop table sxt_student;
drop table sxt_class cascade constraints;
--添加数据
insert into sxt_student values(123,'古力娜扎',202);
insert into student values(sq_class_cid.nextval,'迪丽热巴',206);
insert into sxt_student(sid,sname) values(01,'lisi');
insert into sxt_class values(202,'java33期');
insert into sxt_class values(203,'java34期');
insert into sxt_class values(sq_class_cid.nextval,'java34期');
--删除数据
delete from sxt_class where cid = 202;
delete from sxt_student where sid = 125;

8.主从表关系

当有主从表关系的两张表

1)删除表

(1)默认先删除从表,后删除主表

(2)删除主表并同时删除主外键约束 cascade constraints

2)删除数据

​ 这个主表数据如果没有被从表中的数据引用,可以直接删除

​ 这个主表数据如果已经被从表中的数据引用,需要处理

​ (1)先删除从表中引用了的数据,再删除主表的这个数据

​ (2) 添加外键约束的时候 on delete set null,当主表数据被删除时,从表引用这条数据的外键字段值为null

​ (3) on delete cascade 删除主表数据的时候级联删除从表中引用了的这些数据

rename sxt_student to student;

--序列工具  帮助我们管理为表中的主键字段添加值使用的
--create sequence 序列名 start with 起始值 increment by 步进;
create sequence sq_class_cid start with 200 increment by 1;

--currval 当前值
--nextval 下一个值,获取最新值
--注意:第一次要使用nextval

select sq_class_cid.nextval from dual;
select sq_class_cid.currval from dual;

--删除drop sequence 序列名
drop sequence sq_class_cid;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值