Oracle (03)分组子句.where条件 与 having条件的区别.子查询.DDL.DML.数据的增删改.TCL

版权声明:cxyo.cn https://blog.csdn.net/weixin_44075537/article/details/85033084

昨天作业的回顾 **

  1. 显示员工的id,last_name,salary,部门名称 , 要求, 把没有部门编号的员工也给查询到:

    前置条件:

    公司业务需要, 把员工编号为23 24 25 的员工 分配到了新的部门, 但是部门还未成立! 
    
    update s_emp set dept_id = null where id in(23,24,25);
    commit; 
    

    语句: select e.id,e.last_name,e.salary,d.name from s_emp e,s_dept d where e.dept_id=d.id(+);

  2. 显示每个员工的工资 和对应的工资级别 , 超出工资范围的 也要显示出来 :

    工资表: salgrade

    前置条件:

    公司老板觉得自己的工资太高了, 不合适 , 给自己降了-10000的工资 !  还让自己的秘书 以身作则 , 一起降了工资 !
    
    update s_emp set salary=12500 where id=1;
    update s_emp set salary=500 where id=22;
    commit;
    

    如果在外连接时, 使用between 需要在最小范围后面加入(+) , 最大范围后面加入(+)

    salary between losal(+) and hisal(+)
    

    语句:
    select salary,grade,id,last_name from s_emp e,salgrade g where salary between losal(+) and hisal(+);

  3. 显示每个部门的名称 和 对应的地区的名称, 没有地区编号的也要显示出来 :

    前置条件:
    因为业务需要, 增加了新的部门, 但是还没有确定办公的地点:

    insert into s_dept values(99,'chiji',null);
    commit;
    
    select d.name,r.name from s_dept d,s_region r where d.region_id = r.id(+);
    

group by having 分组子句 **

格式 … group by 分组标准字段 having 分组过滤条件

分组标准字段: 指的是查询的结果, 按照什么字段进行分组 ,例如: s_emp表格按照部门编号分组!
分组过滤条件: 对分组后的数据, 进行过滤

分组查询的限制:

在带有分组的查询语句中, select与from中间编写的查询字段, 只能存在两种:  

    -   分组标准字段  (在一个组中唯一的)
    -   组函数的结果  (统计一个组中的某数据, 也是只有一个的)

    上面这两种可以查询的数据类型,  都是为了保证分组后的查询的列数据能一一对应!

分组查询:

1.  按照部门的编号进行分组 , 统计每个部门的人数 !
select dept_id,count(*) from s_emp group by dept_id;

2.  按照部门的编号进行分组, 统计每个部门的最高薪资,要求,部门人数低于3的不显示!
select dept_id,max(salary) from s_emp group by dept_id having count(*)>2;   

3.  按照部门编号进行分组, 显示部门的编号, 平均薪资 , 平均薪资高于1400的才展示出来!
select dept_id,avg(salary) from s_emp group by dept_id having avg(salary)>1400; 

4.  统计每个部门中薪资大于1400的人数 , 低于2人的不显示 !

select dept_id,count(*) from s_emp where salary>1400 group by dept_id having count(*)>1;

5.  按照 部门编号分组 , 显示部门的人数, 部门的编号, 部门的名称

select count(*),dept_id,max(name) from s_emp e,s_dept d where e.dept_id = d.id group by dept_id;        

分组过程中 容易出现的bug **

  1. 按照部门的编号进行分组 , 统计每个部门的人数 !
    select id from s_emp group by dept_id;
    select id,count(*) from s_emp group by dept_id;
    select dept_id,id from s_emp group by dept_id;

上述三行代码都出现了错误:

ORA-00979: 不是 GROUP BY 表达式
00979. 00000 -  "not a GROUP BY expression"

原因在于, 数据的结果 , 没有一一对应!

select与from中间编写的查询字段, 只能存在两种:

    -   分组标准字段  (在一个组中唯一的)
    -   组函数的结果  (统计一个组中的某数据, 也是只有一个的)

where条件 与 having条件的区别 *****

  • where 条件 对表格中所有的数据 进行过滤!
  • having 条件 是对于分组后的组中数据进行过滤!
  • where条件执行在having之前

select语句 *****

完整格式:

select 字段 from 表名/视图 [where条件] [group by 分组标准字段 [having 过滤条件]] [order by 排序字段 排序规则]

执行顺序

from--> where条件 -->group by -->having条件-->select -->order by

子查询 ***

概念: 把一个select 语句的查询结果, 当作另一个select 语句的一部分 !

子查询的子语句, 使用小括号括住!

子查询的语句, 可以出现的位置有三个:

1.  应用到from 之后
2.  应用到where之后
3.  应用到having之后

应用到where条件之后

把一个select的结果, 当前where后的筛选条件 !

案例: 查询id最大的员工信息(id,salary,last_name)

步骤1.    先得到最大的id
select max(id) from s_emp;

步骤2.    根据最大的id 进行信息的查询
select id,salary,last_name from s_emp where id=(select max(id) from s_emp);

练习:查询部门编号最大的部门员工信息(id,salary,last_name) !

步骤1. 得到最大的部门编号
select max(dept_id) from s_emp;

步骤2. 根据得到的部门编号进行查询
select id,salary,last_name from s_emp where dept_id=(select max(dept_id) from s_emp);

练习: 查询公司所有的领导
1. 先查寻到公司所有的领导id(manager_id) , 并去重
select distinct manager_id from s_emp;
select distinct manager_id from s_emp where manager_id is not null;

2.  根据上面查询到的领导id , 通过in去匹配公司的所有领导
    select id,last_name,salary from s_emp where id in(select distinct manager_id from s_emp where manager_id is not null);

练习: 查询公司所有的普通员工
1. 先查寻到公司所有的领导id(manager_id) , 并去重
select distinct manager_id from s_emp where manager_id is not null;

2.  根据上面查询到的领导id,通过not in匹配公司所有的普通员工!
    select id,last_name,salary from s_emp where id not in(select distinct manager_id from s_emp where manager_id is not null);

应用到having之后

把一个select语句的结果, 当作另一个分组查询语句 分组后的组过滤条件!

寻找部门平均薪资 大于 32号部门平均薪资的 部门信息 : 显示部门编号 和 平均薪资!

步骤1.    先找出32号部门的平均薪资
select avg(salary) from s_emp where dept_id=32;

步骤2.  根据部门进行分组查询, 过滤条件为: 计算后部门的平均薪资大于上面 查询的结果

select dept_id,avg(salary) from s_emp group by dept_id having avg(salary)>(select avg(salary) from s_emp where dept_id=32);

应用到from之后

每一个select语句的结果, 就类似存在与内存中的一个表.

把select语句要查询的表格 , 更改为另一条查询语句, 即可!

案例: 查询员工的id,last_name,salary,条件为薪资大于1400

select id,last_name,salary from s_emp where salary>1400;

根据上次查询的结果, 使用子查询更快的获取员工id为5的员工信息id,last_name,salary,

select * from (select id,last_name,salary from s_emp where salary>1400) where id=5;

DDL (数据定义语句)
创建表 *****

数据类型:

-   number:     数字类型
-   varchar2:   变长字符串 ,编写为varchar也可以使用, 会自动转换为varchar2
-   date:       日期类型

创建表格的格式:

create table 表名(
字段1 数据类型(长度),
字段2 数据类型(长度),

字段n 数据类型(长度)
);

注意: 关于number类型长度的编写,如下所示:

id number(2,3): 2表示整数长度为2,最大能存储99 , 3 表示小数点后长度为3位

练习:

创建一个表格person15
字段: 
    1.  id 长度为5 , 小数点后允许0位的number类型数据
    2.  name 长度为10的varchar2类型的数据
    3.  age长度为3,小数点后允许0位的number类型数据

create table person15(
id number(5,0),
name varchar2(10),
age number(3,0)
);

练习:

创建一个表格
表名为: user15
字段:
    1.  id 长度为5的number类型
    2.  uname 长度为32的varchar2类型
    3.  upass 长度为32的varchar2类型

create table user15(
    id number(5),
    uname varchar2(32),
    upass varchar2(32)
);
id uname  upass
1   aaa   bbb


create table userPhoneNumber(
    userid number(5),
    phoneNumber number(11)
);
userid   phoneNumber
1        13843838438

删除一个表格 *****

格式: drop table 表名;

注意: 在删除一个表格时, 如果此表格与外部其他表格不存在任何数据和格式上的关联 , 则会立即被删除

在表格删除时, 同时表格中的数据也会被清空!

练习:

    删除你的person表和user15表

语句: drop table person15;
drop table user15;

修改表结构 (了解)

很耗费系统的性能:

修改表结构的流程: 
1.  先将表格中的数据备份
2.  将表格清空, 修改结构
3.  将备份的数据 依次插入

如果表格在创建时就有缺陷怎么办?

两种方案:  

    1.  更改 
    2.  扩展表格 进行关联

其实更多的时候 ,我们应尽量避免 表格被重构 !

在设计表格时, 应尽量的让表格中的字段完善 !  并设置保留字段 ,留待以后添加新的业务 !

修改表结构的两种操作

  1. 删除表中的字段

    格式: alter table 表名 drop column 列名;

    练习:

    创建上面案例的person15 和 user15
    
    删除person15中的age字段
    

    alter table person15 drop column age;

  2. 添加表中的字段

    格式: alter table 表名 add 字段名 数据类型(长度);

    练习:

    向person15表中添加一个age字段 长度为3  nummber类型
    

    alter table person15 add age number(3);

DML 数据操作语言

对于数据库中表格数据的 添加 , 删除 修改

事务: 将一系列的dml语句 看作一个业务流程 , 看作一个整体, 统一进行处理, 要么一起成功, 要么一起失败!

关于DML语句 , 所有的操作, 都需要提交事务 !

在Oracle数据库中 事务的自动提交 是关闭的 !

提交事务 *****

commit;

事务回退 **

rollback;

INSERT语句 插入数据 *****

  1. 全字段添加数据

    格式: insert into 表名 values(数据列表);

    注意: 数据列表 , 表示的是要插入的数据列表 ,传入的顺序, 按照字段创建的顺序来插入 , 多个值之间使用逗号隔开

    数据列表中的顺序, 是按照创建时字段的顺序插入的
    但是对于表格的修改(增加删除字段), 会影响到字段的顺序 !
    

练习:

向user15表格中注册一组用户: 

1.  id:10001 , 帐号:dongfei 密码:ytdhytytwj
insert into user15 values(10001,'dongfei','ytdhytytwj');
2.  id:10002 , 帐号:gaofan  密码:lzlhlzlh
insert into user15 values(10002,'gaofan','lzlhlzlh');
3.  id:10003 , 帐号:gaosen  密码:hahahahaha
insert into user15 values(10003,'gaosen','hahahahaha');
4.  id:10004 , 帐号:lukuan  密码:wdjzdbshjsa
insert into user15 values(10004,'lukuan','wdjzdbshjsa');
5.  id:10005 , 帐号:yuhang  密码:dgnmadgnl
insert into user15 values(10005,'yuhang','dgnmadgnl');
-- 不要忘记提交事务啊
commit;
  1. 选择字段插入数据

    格式: insert into 表名(插入的字段列表) values(数据列表);

    数据列表: 它数据顺序, 与前面的字段列表一致 !

    注意: 也可以选择全部字段, 来进行数据的添加! 例如如下两段语句 作用相同:

    insert into user15 values(10003,‘gaosen’,‘hahahahaha’);
    insert into user15(id,uname,upass) values(10003,‘gaosen’,‘hahahahaha’);

    练习:
    向数据库中的user15表格 插入一组数据

    1. id:10006 , 帐号:dongfei
      insert into user15(id,uname) values(10006,‘dongfei’);
    2. id:10007 , 帐号:gaofan
      insert into user15(id,uname) values(10007,‘gaofan’);
    3. id:10008 , 帐号:gaosen
      insert into user15(id,uname) values(10008,‘gaosen’);
    4. id:10009 , 帐号:lukuan
      insert into user15(id,uname) values(10009,‘lukuan’);
    5. id:10010 , 帐号:yuhang
      insert into user15(id,uname) values(10010,‘yuhang’);
      – 不要忘记提交事务啊
      commit;

数据的删除*****

格式1: 一次删除一个表格中的所有数据行

格式: delete from 表名;

练习: 删除user15表格中的所有数据

delete from user15;

格式2: 根据where条件, 删除匹配的数据行

格式: delete from 表名 where 条件;

练习: user15表格中id为10001,10002,10003的用户 ,要求使用1行语句完成!
delete from user15 where id<10004;

注意:

where 条件的使用 与 select语句中基本一致!

数据的修改*****

格式: update 表名 set 字段名1=字段值1,字段名2=字段值2 … 字段名n=字段值n [where条件];

如果在修改时, 不添加where条件, 则表示修改表中的所有数据 !

添加where条件后, 表示修改匹配条件的数据行!

案例: 修改user15表格中 id为10001的用户的 密码为 123456

update user15 set upass='123456' where id=10001;
 commit;

练习: 修改user15表格中的 帐号为gaosen的用户的信息, 修改密码(upass)为234567
update user15 set upass=‘123456’ where uname=‘gaosen’;
commit;

练习: 修改user15表格中的 所有用户的帐号(uname)为******
update user15 set uname=’******’;
commit;

TCL事务控制语句

事务: 将一系列的dml语句 看作一个业务流程 , 看作一个整体, 统一进行处理, 要么一起成功, 要么一起失败!

关于DML语句 , 所有的操作, 都需要提交事务 !

在Oracle数据库中 事务的自动提交 是关闭的 !

在mysql中 事务是自动提交的 ! 在JDBC中事务是自动提交的

事务特性***

  1. 原子性: 同一个事务中的多个DML操作, 不可分割 要么一起成功, 要么一起失败!
  2. 一致性:通一个事务的操作, 结果应保持一致!
  3. 隔离性:同一个事务的dml操作, 在没有提交之前,对于其他的事务来说, 数据应是被隔离的 ,不可见的!
  4. 持久性:存储的数据要保持一直存在!

如何开始一个事务

从上一次事务的结束之后, 进行的第一次dml操作, 就自动开启了事务!

如何结束一个事务

结束事务有两种不同的操作:

  1. 提交事务commit;

    结束事务, 并将事务中所有的dml操作提交, 将数据的更改 添加 删除 应用到数据库中!

  2. 事务回退rollback;
    也称为事务的回滚 , 表示本次事务中 所有的dml操作 撤回 ! 不对数据库中的数据 产生任何的更改!

    关于回退事务, 有两种不同的操作:

    1. 一次回退所有dml操作 ***
      使用格式: rollback;

    2. 回退到某一个保存点 了解
      使用格式: rollback to 保存点名称;

    添加一个保存在: 在任意的dml语句后, 加入: savepoint 名称; 即可完成保存点的添加!

    案例:

    对user15表格进行数据的添加: 
    
     --1.   id:10006 , 帐号:dongfei 
    insert into user15(id,uname) values(10006,'dongfei');
    --2.    id:10007 , 帐号:gaofan  
        insert into user15(id,uname) values(10007,'gaofan');
    commit;
    --3.    id:10008 , 帐号:gaosen 
        insert into user15(id,uname) values(10008,'gaosen');
    --4.    id:10009 , 帐号:lukuan  
        insert into user15(id,uname) values(10009,'lukuan');
    --5.    id:10010 , 帐号:yuhang
        insert into user15(id,uname) values(10010,'yuhang');  
    -- 不要忘记提交事务啊
    rollback;
    

    添加保存点的案例:

    对于person15表格进行数据的插入
    
    insert into person15 values(1,'董飞',8);
    insert into person15 values(2,'董飞',18);
    savepoint a;
    insert into person15 values(3,'董飞',28);
    savepoint b;
    insert into person15 values(4,'董飞',38);
    savepoint c;
    insert into person15 values(5,'董飞',8);
    savepoint d;
    rollback b;
    commit;
    

猜你喜欢

转载自blog.csdn.net/weixin_44075537/article/details/85033084