2021.07.29 Oracle学习笔记 2

99语法

        select 数据(*|字段,字段|伪列) from 数据源(表|结果集|视图) where 行过滤条件 group by 分组字段 having 组过滤条件 order by 排序字段

        多表连接
        查询30部门员工信息以及员工所在部门信息以及员工薪资登记信息 

select * from emp e,dept d,salgrade s where e.deptno=d.deptno and e.sal between s.losal and s.hisal and  e.deptno = 30

        99链表查询

        笛卡尔积   cross join 

select * from emp e,dept d; --92
select deptno from emp e cross join dept d;  --99

 等值连接

        自然连接 natural join   自动根据同名字段,主外键关联关系 字段做等值连接

        select deptno from emp e natural join dept d;
注意: 在自然连接中同名字段不能指明出处

        join using(自动做等值连接的同名字段)... 

       select deptno from emp e inner join dept d using(deptno);
注意: 在join using中同名字段不能指明出处

非等值连接 

         数据源1 join 数据源2 on 表连接条件 可以做等值,可以做非等值

select e.deptno from emp e join dept d on e.deptno = d.deptno;
       
--查询员工信息以及员工工资等级信息
select * from emp e inner join salgrade s on e.sal between s.losal and s.hisal;
--查询员工信息以及所在部门信息以及员工工资等级信息,以及上级经理人信息
       select *
         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 e2
           on e.mgr = e2.empno
           where deptno in (10,30);

内连接 : 满足连接条件才能显示 (inner) join

外连接 : 有的表中的数据不满足连接条件也显示
      主表: 不满足连接条件也显示
      左连接 : left join
      右连接 : right join
      全连接 : full join 两张表都作为主表

select * from emp e1 full join emp e2 on e1.mgr=e2.empno; 

 decode(判定字段,值1,结果1,值2,结果2...,默认值)

select deptno,dname,loc, decode(deptno,10,'十',20,'二十',30,'三十','四十')   中文名称 from  dept;

case when then else end 

select deptno,dname,loc, (case deptno when 10 then '十' when 20 then '二十' else '其他' end)中文名称 from dept;

在下面的数据源做查询

 /* id name course score

  1 张三  语文  81
  2 张三  数学  75
  3 李四  语文  81
  4 李四  数学  90
  5 王五  语文  81
  6 王五  数学  100
  7 王五  英语  90*/
  create table tb_student(
    id number(4) ,
    name varchar2(20),
    course varchar2(20),
    score number(5,2)
  );
  insert into tb_student values(1,'张三','语文',81);
  insert into tb_student values(2,'张三','数学',75);
  insert into tb_student values(3,'李四','语文',81);
  insert into tb_student values(8,'李四','英语',90);
  insert into tb_student values(4,'李四','数学',90);
  insert into tb_student values(5,'王五','语文',81);
  insert into tb_student values(6,'王五','数学',100);
  insert into tb_student values(7,'王五','英语',90);
  commit;
  drop table tb_student cascade constraints;
--使用一条sql语句,查询每门课都大于80分的学生姓名

select * from tb_student;

--分析:
--数据: 学生姓名
--来源: tb_student
--条件: 1)有几门可就考了几门课   2)没门课程分数>80  以人名为单位,每组的最小分数>80
--一共存在几门课程
select count(distinct course) from tb_student;

select name
  from tb_student
 group by name
having min(score) > 80 and count(1) = (select count(distinct course)
                                         from tb_student);

--行转列  -->分组,判定函数

select name,
       decode(course, '语文', score) 语文,
       decode(course, '数学', score) 数学,
       decode(course, '英语', score) 英语
  from tb_student;
  
select name,
       max(decode(course, '语文', score)) 语文,
       min(decode(course, '数学', score)) 数学,
       min(decode(course, '英语', score)) 英语
  from tb_student group by name;

 rowid 与 rownum 都做伪列存在

        rowid : 行记录的地址,行的唯一标识,数据插入到表中的是决定 

可以实现去重: 对没有主键|唯一字段的表中多条完全重复的数据,根据rowid实现去重
去重: 如果表中存在主键或者唯一字段,直接 根据主键或者唯一字段去重

select rowid,rownum from dept;
/*
  insert into tb_student values(1,'张三','语文',81);
  insert into tb_student values(2,'张三','数学',75);
  insert into tb_student values(3,'李四','语文',81);
  insert into tb_student values(8,'李四','英语',90);
  insert into tb_student values(4,'李四','数学',90);
  insert into tb_student values(5,'王五','语文',81);
  insert into tb_student values(6,'王五','数学',100);
  insert into tb_student values(7,'王五','英语',90);
  commit;
*/
select id,name,course,score from  tb_student;

--查询到要保留的数据
select max(rowid) from tb_student group by id,name,course,score;  --要保留的8条数据的rowid
select *
  from tb_student
 where rowid in
       (select max(rowid) from tb_student group by id, name, course, score);

--查询到要删除的数据
select *
  from tb_student
 where not rowid in
       (select max(rowid) from tb_student group by id, name, course, score);

--删除这些数据
delete from tb_student
 where not
        rowid in
        (select max(rowid) from tb_student group by id, name, course, score);

         rownum 结果集的序号

--规律: 从1开始,每次+1
select * from (select empno,ename,job,mgr,rownum num from emp) where num >=5;

--一个select查询语句就有一个结果集,每一个结果集中数据都有自己的序号-->rownum
--注意: 当需要使用rownum进行一些判定,需要对一个已经确定的结果集的rownum进行判定
--rownum与排序: 
/*
      一般规律为:
              根据非主键字段排序,先确定rownum再排序
              根据主键字段排序,先排序,后确定rownum                                
*/
select empno,ename,sal,rownum from emp order by sal;
select deptno,dname,loc,rownum from dept order by deptno desc;

--如何实现在有排序存在的情况下,保证rownum是规律的,从小到大的
select empno,ename,sal,n,rownum num from (select empno,ename,sal,rownum n from emp order by sal);

--分页
select *
  from (select empno, ename, sal, rownum num
          from (select empno, ename, sal from emp order by sal))
 where num >= 7
   and num <= 9;

视图与索引 

        视图 : 表与结果集之间

                逻辑视图: 不会存储数据,数据来资源原始表结构,起到封装,简化,提高复用性的作用
                物理视图: 真实存储数据 

        作用: sql语句的封装与简化,提高复用性,安全性

 授权: 
          a)、sys登录    
          b)、授权: grant dba to SCOTT;
          ​	  回收: revoke dba from SCOTT;
          c)、重新登录
--create or replace view 视图名 as select语句 [with read only];
create or replace view vw_haha as select empno,ename,sal,comm,deptno from emp where deptno = 20 with read only;

select * from vw_haha;
--修改视图中的数据其实是修改原有表机构中的数据,视图不存储数据
update vw_haha set sal=8000 where empno = 7369;

select * from emp;

update emp set sal=800 where empno = 7369;

--删除视图
drop view vw_haha;

索引 

  1. 帮助提高查询效率
  2. 索引为表中的字段添加索引
  3. 大量数据的前提下,通过索引对某个字段的数据做查询,效率会大大提高
  4. 索引也是对象,需要通过是数据库维护
  5. 索引类似与目录
  6. 如果大量做根据字段做查询,少量做增删适合使用索引
  7. 如果大量根据字段做增删,少量查询,每次增删数据需要根据维护索引,会降低效率
--oracle自动为主键添加索引
select * from emp where sal>1500;

--为emp表的sal字段添加索引
--create index 索引名 on表名 (字段列表...)
create index index_emp_sal on emp(sal);
--drop  index 索引名
drop index index_emp_sal;

--注意: 唯一性较好字段适合建立索引



--查询每一个部门中领导人的平均薪资最低的部门编号
--1)找到所有的领导人
select * from emp where empno in(select distinct mgr from emp where mgr is not null);
--2)按照部门分组找到领导的最低平均工资
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;

--3)找到平均工资与最低平均工资相等的部门编号
select deptno,avg(sal) from emp where empno in(select distinct mgr from emp where mgr is not null) group by deptno having avg(sal) = (最低平均工资);

--部门编号
select deptno
  from emp
 where empno in (select distinct mgr from emp where mgr is not null)
 group by deptno
having 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 in
       (select deptno
          from emp
         where empno in (select distinct mgr from emp where mgr is not null)
         group by deptno
        having avg(sal) = (select min(avg(sal))
                            from emp
                           where empno in (select distinct mgr
                                             from emp
                                            where mgr is not null)
                           group by deptno));

表设计

        根据业务需求,满足三范式要求

        三范式:

                1)列不可再分,字段的原子性

                2)定义主键(唯一+非空),确定唯一

                3)拆分表,通过主外键约束定义两张表的关系 ,消除传递依赖,避免数据的过渡冗余

          表名
          确定表中的字段
          字段: 字段名  数据类型  字段的约束(要求)   
          数据 

表与表之间的关系
        一对一 : 用户  身份证   -->主外键
        一对多|多对一 : 学生 与 班级  -->主外键
        多对多 : 订单与商品   学生与课程  --> 中间表

DDL  create创建表
create 表名(
       字段名 字段类型,
       字段名 字段类型,
       .....
       字段名 字段类型
)

--班级表
create table yjx_class(
       cid number(5) constraint pk_cls primary key,
       cname varchar2(15) not null  
)
--学生表
create table yjx_student(
       sid number(5) primary key,
       sname varchar2(15) not null,  --(2 char) 2个字符  否则默认字节数
       sgender char(3) check(sgender in ('男','女')),
       birthday date default(sysdate),
       cid number(5) ,--references yjx_class(cid)
       --为指定的字段添加约束
       constraint fk_cls_id foreign key(cid) references yjx_class(cid) 
)

--表 结构之后追加约束
--alter table tb_user add constraint uq_user_email unique(email);

select * from t_user;

 添加约束

  1.  主键约束 : 唯一+非空   primary key
  2. 唯一约束 : unique
  3. 非空约束 : not null
  4. 默认约束 : default(默认值)
  5. 外键约束 : references 
  6. 检查约束 : check(检查条件) 

      在创建表时候添加约束

  1. 创建表结构的时候,字段的后面直接添加约束 --> 方便简单,不需要指定字段名,不能指定约束名
  2. 创建表结构的时候,字段的后面直接添加约束,同时指定约束名
  3. 创建表结构的结束之前,字段的定义之后位置,为某个字段添加某种约束,可以指定约束名
  4. 表结构创建之后追加约束  

注意: 不建议为表结构中的字段大量添加约束
        物理约束 : 表的字段上添加约束 :   主外键约束
        逻辑约束 : 代码层面上添加约束 :   检查约束 

注释

comment on table yjx_student is '学生表';
comment on column yjx_student.sid is '学生编号,主键';

--create table 表名 as select 字段列表 from 已有表 where 1!=1; 

--创建表+拷贝数据
create table haha as select empno,ename,sal from emp;
--创建表+不拷贝数据
create table haha as select empno,ename,sal from emp where 1!=1;
select * from haha;

--约束的禁用与启用
ALTER TABLE yjx_student disable constraint fk_cls_id;
ALTER TABLE yjx_student enable constraint fk_cls_id;


insert into yjx_student values(1001,'zhangsan','男',sysdate,900);

select * from yjx_student;

--删除约束 ,可以级联删除
--alter table tb_user  drop constraint uq_user_email  cascade;
alter table yjx_class  drop constraint SYS_C007316  cascade;

 DDL : 数据定义语言

        drop 删除表
        drop table 表名;
        注意: 如果两张表具有主外键关联关系,从表可以直接删除
               删除主表: 1) 默认先删除从表,再删除主表  

                                2)级联删除 : 删除主表的同时,级联删除主外键约束

      drop table haha;
      drop table yjx_student;
      drop table yjx_class cascade constraints;
      
      --alter 修改表结构
      --create 创建
      
      select * from t_user;
      --修改列名
      alter table t_user  rename column  userid to id;

DML 数据管理语言

        数据的增insert 删delete 改update

        数据的查询 DQL 

在对表中数据做增删改自动开启事务,需要提交或者回滚 

--insert
      --insert into 表名 values(值列表 );
      insert into t_user values (1001,'zhangsan','女',sysdate);
      --insert into 表(指定列) values(值列表);
      insert into t_user(id,username) values(seq_user_id.nextval,'lisi');
      --insert into 表名 select 查询列 from 源表 where 过滤数据; 
      insert into t_user select empno,ename,hiredate from emp where deptno = 30;
     --insert into 表(指定列) select 查询列 from 源表 where 过滤数据; 
     insert into t_user(id,username) select deptno,dname from dept;

 序列工具

        帮助管理类似主键字段的值

        序列与表与字段不绑定 

        序列第一次需要获取nextval

--创建 create sequence 序列名  start with  起始值  increment by 步进;
create sequence seq_user_id  start with  1003  increment by 1;

--获取当前序列工具的当前值
select seq_user_id.currval from dual;

--获取当前序列工具的下一个值|最新值
select seq_user_id.nextval from dual;

--drop  sequence 序列名;
drop  sequence seq_user_id;

----删除列
alter table t_user drop column gender;


--修改 update 表名 set 字段=值 [,....] where  过滤行记录;
update t_user set regdate=sysdate where 1=1;-- 修改所有数据的指定字段值
update t_user set username='zhangsanfeng' where id = 1001; ---- 修改满足条件数据的指定字段值

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值