当前位置: 首页 > news >正文

数据库补充笔记2

Oracle

命令分类操作:

分类

命令

DDL

create:创建;drop:删除;alter:修改;rename: 重命名; truncate:截断

DML

insert:插入;delete:删除;update:更新;select:查询

DCL

grant:授权;revoke:回收权利;commit:提交事务;rollback:回滚事务

查询列(字段)

  • select distinct *|字段|表达式 as 别名 from 表 表别名
  • SELECT * FROM 表名; ->查询某个表中所有的记录的所有字段信息
  • SELECT 列名 FROM 表名; ->查询某个表中所有的记录的指定字段信息
  • SELECT 列名1,列名2 FROM 表名; -> 查询某个表中所有的记录的字段1 字段2
  • SELECT distinct 列名 FROM 表名; ->去除重复记录
  • SELECT 表达式 FROM 表名; ->查询表达式
  • SELECT xxx as 别名 FROM 表名 表别名 ->使用别名

部分列

查询部分字段,指定的字段名:

--1)、检索单个列
select ename from emp; --查询雇员姓名
--2)、检索多个列
select deptno,dname,loc from dept; --查询部门表的deptno,dname, loc 字段的数据。
--以下查询的数据顺序不同(查询的字段顺序代表数据顺序)
select loc,dname,deptno from dept;
select deptno,dname,loc from dept;

所有列

--1)、检索所有列1
select * from dept; --查询部门的所有信息
--2)、检索所有列2
select deptno,dname,loc from dept; --查询部门的所有信息

去除重复

使用distinct去重,确保查询结果的唯一性

select distinct deptno from emp; --去重

别名

使用别名便于操作识别 、隐藏底层信息。存在字段别名和表别名

select ename as "雇员 姓名" from emp;
select ename "雇员姓名" from emp;
select ename 雇员姓名 from emp;
select ename as 雇员姓名 from emp;
select ename as " Ename" from emp;

  • as: 字段别名可以使用as;表别名不能使用as
  • "":原样输出,可以存在 空格与区分大小写

null

null 遇到数字参与运算的结果为 null,遇到字符串为空串

select 1+null from dual;
select '1'||null from dual;
select 1||'2'||to_char(null) from dual;
select ename,sal*12+comm from emp;
--nvl内置函数,判断是否为null,如果为空,取默认值0,否则取字段实际值 select
ename,sal*12+nvl(comm,0) from emp;

比较条件

= 、>、 <、 >=、 <=、 !=、 <>

select * from emp where deptno !=20;
select * from emp where deptno <>20;
select * from emp where sal between 800 and 950; --between and是成对出现的
--查询 员工的年薪大于20000的 员工名称、岗位 年薪
--1)、nvl
select ename,job,12*(nvl(comm,0)+sal) income from emp;
--2)、年薪大于20000
--错误不能使用别名: select ename,job,12*(nvl(comm,0)+sal) income from emp where
income>2000;
--a)、嵌套一个: 查询在前 过滤在后
select ename,job,income from
(select ename,job,12*(nvl(comm,0)+sal) income from emp) where income>2000;
--b)、不使用别名 (推荐) :过滤在前,查询在后
select ename,job,12*(nvl(comm,0)+sal) income from emp where 12*(nvl(comm,0)+sal)
>2000 ;
--了解 any some all
-- >=any(值列表) 大于最小值<=any(值列表)小于最大值
select * from emp where sal >=any(900,2000);
select * from emp where sal <=any(900,2000);
-- some与any 一样的效果
-- all 大于最大值 小于最小值
select * from emp where sal >=all(900,2000); select * from emp where sal
<=all(900,2000);
--查询 工种为’SALESMAN’的员工信息 (注意 内容区分大小写)
--检索 工资 大于 2000员工名称 岗位 工资
--检索 工资 小于 3000员工名称 岗位 工资
--检索 工资 2000, 3000员工名称 岗位 工资
--查询部门编号为20的员工名称

like :模糊查询

模糊查询,使用通配符:

  • %:零个及以上(任意个数的)的字符
  • _:一个字符
  • 遇到内容中包含 % _ 使用escape('单个字符')指定转义符

--查询员工姓名中包含字符A的员工信息
select * from emp where ename like '%A%';
--查询员工姓名中包含第二个A的员工名称信息
select * from emp where ename like '_A%';
% ,如何查找:
--1)、编写测试数据
insert into emp(empno,ename,sal) values(1000,'t_%test',8989); insert into
emp(empno,ename,sal) values(1200,'t_tes%t',8000);
--2)、查找
--查询员工姓名中包含字符%的员工名称 岗位 工资 部门编号
select ename,job,sal,deptno from emp where ename like '%a%%' escape('a');
--查询员工姓名中包含第二个_的员工名称 岗位 工资 部门编号

in exists

in相当于使用or的多个等值,定值集合 ,如果存在 子查询,确保 类型相同、字段数为1,如果记录多,效率不高,用于 一些 少量定值判断上

select * from emp where sal in(900,800);
--子查询(查询中再有查询) in 只能存在一个字段
select * from emp where sal in (select sal from emp e where deptno=10);
--10或30部门的雇员信息
select * from emp where deptno in(10,30);
--部门名称为 SALES 或 ACCOUNTING 的雇员信息
select deptno from dept where dname in('SALES','ACCOUNTING'); SELECT *
FROM emp
WHERE deptno IN
(SELECT deptno FROM dept WHERE dname IN ('SALES', 'ACCOUNTING'));
/*
便于理解 使用java思维
while(外层结果集){
while(内层结果集){
	if(emp.deptno==10){
		syso("....");
	}
	if(emp.deptno==30){
		syso("....");
	}
}
}
==>in :如果记录多,效率不高,用于 一些 少量定值判断上
*/

exists条件为true,存在记录则返回结果,后续不再继续 比较查询,与查询的字段无关,与记录有关

--exists :条件为true,存在记录,则返回结果,后续不再继续 ,与字段无关,与记录有关
--exists 难点: 外层结果集 内层结果集 关系列(没有关系列 true)
/*
while(外层结果集){
while(内层结果集){
if(emp.deptno==dept.deptno||true){
syso("....");
break; //跳出本层
}
}
}
*/
--无关系列
/**
while(emp 的14条记录){
while(dept的2条记录){
if(true){
syso();
break;
}
}
}
*/
select *
from emp
where exists
(select deptno,dname from dept where dname in ('SALES', 'ACCOUNTING'));
--加入关系列
/**
while(emp 的14条记录){
while(dept的2条记录){
if(e.deptno=d.deptno){
syso();
break;
}
}
}
*/
select *
from emp e
where exists (select deptno, dname
from dept d
where dname in ('SALES', 'ACCOUNTING')
and e.deptno = d.deptno);
/**
while(emp 的14条记录){
while(dept的2条记录){
if(e.deptno!=d.deptno){
syso();
break;
}
}
}
*/
select *
from emp e
where exists (select deptno, dname
from dept d
where dname in ('SALES', 'ACCOUNTING')
and e.deptno != d.deptno);
--分析以下结果
select *
7.2.7. 获取所有行的记录
7.2.8. 排序
使用 ORDER BY 排序,排序不是真实改变存储结构的顺序,而是获取的集合的顺序。
顺序 :asc(默认) desc
多字段: 在前面字段相等时,使用后面的字段排序
空排序: 降序为 desc,注意 null 为最后
from emp e
where not exists
(select deptno, dname
from dept d
where dname in ('SALES', 'ACCOUNTING')
and e.deptno = d.deptno);
select ename, sal
from emp
where sal in (select sal from emp e2 where e2.sal >= 2000);
select ename, sal
from emp
where exists (select ename, sal from emp e2 where e2.sal >=
2000); --exists
select empno, ename, sal
from emp e1
where exists (select empno, ename, sal, comm
from emp e2
where comm is not null
and e1.empno = e2.empno);
select empno, ename, sal
from emp e1
where exists (select empno, ename, sal, comm
from emp e2
where comm is not null
and e1.deptno = e2.deptno);

排序

使用 ORDER BY 排序,排序不是真实改变存储结构的顺序,而是获取的集合的顺序。

  • 顺序 :asc(默认) desc
  • 多字段: 在前面字段相等时,使用后面的字段排序
  • 空排序: 降序为 desc,注意 null 为最后

--按工资降序
select * from emp order by sal desc;
--null问题
select * from emp order by nvl(comm,0),comm desc;
select * from emp order by comm nulls first;
--查询雇员姓名,年薪 按佣金排序 默认为升序(asc),降序为desc,注意null为最后
select ename,(sal+nvl(comm,0))*12,comm total from emp order by comm desc;
--查询雇员姓名,年薪 按佣金排序 默认为升序(asc),降序为desc,注意null为最后
select ename,(sal+nvl(comm,0))*12,comm total from emp order by comm desc;
7.3. 作业
1. 使用基本查询语句.
(1)查询DEPT表显示所有部门名称.
(2)查询EMP表显示所有雇员名及其全年收入(月收入=工资+补助),处理NULL行,并指定列别名为"年
收入"。(NVL(comm,0) comm取空值时用0替代)
(3)查询显示不存在雇员的所有部门号。
2. 限制查询数据
(1)查询EMP表显示工资超过2850的雇员姓名和工资。
(2)查询EMP表显示工资不在1500~2850之间的所有雇员及工资。
(3)查询EMP表显示代码为7566的雇员姓名及所在部门代码。
(4)查询EMP表显示部门10和30中工资超过1500的雇员名及工资。
(5)查询EMP表显示第2个字符为"A"的所有雇员名其工资。
(6)查询EMP表显示补助非空的所有雇员名及其补助。
3. 排序数据
(1)查询EMP表显示所有雇员名、工资、雇佣日期,并以雇员名的升序进行排序
(2)查询EMP表显示在1981年2月1日到1981年5月1日之间雇佣的雇员名、岗位及雇佣日期,并以雇
佣日期进行排序。
(3)查询表显示获得补助的所有雇员名、工资及补助,并以工资升序和补助降序排序。
8. 函数
函数分为系统内置函数 自定义函数(后期学习的 plsql 中定义);了解系统内置函数(方法),重点掌
握 to_date,to_char (字符和日期的转换)根据函数的返回结果,我们将函数分为单行函数和多行函
数
--对部门编号为 20 或30的雇员,工资+佣金 进行升序排序,如果相同,则按姓名降序。
--1、查询20、30 雇员
select * from emp where deptno in(20,30);
--2、工资+佣金排序
select ename,sal,comm,sal+nvl(comm,0) c from emp where deptno in(20,30) order by
c;
--3、多个字段排序使用, 排序的字段可以使构建出来的虚拟的字段
select ename,sal,comm from emp where deptno in(20,30) order by
sal+nvl(comm,0),ename desc;

转换函数(重点)

  • to_date(c,m) -> 字符串以指定格式转换为日期
  • to_char(d,m) -> 日期以指定格式转换为字符串

select to_date('2017-3-21 18:12:12', 'yyyy-mm-dd hh24:mi:ss') time from dual; 

select to_char(sysdate, 'yyyy-mm-dd') from dual; 

select to_char(sysdate, 'yyyy/mm/dd') from dual; 

select to_char(sysdate, 'yyyy\mm\dd') from dual; 

--注意中文的问题 

--select to_char(sysdate,'yyyy年mm月dd日') from dual; 

select to_char(sysdate, 'yyyy"年"mm"月"dd"日"') from dual;

count: 统计

--1、count统计所有的员工数
--1)、*
--2)、主键
--3)、推荐
select ename,1 from emp;
select count(1) from emp where 1=1;
--2、null不参与运算
--存在佣金的员工数
--不推荐/不需要
select count(comm) from emp where comm is not null; --推荐
select count(comm) from emp;
--统计 部门编号30的员工数
select count(1) from emp where deptno=30;
--统计数量过程中 ,可能处理重复
--统计 存在员工的 部门数量
select count(distinct(deptno)) 有人的部门 from emp;
--统计10和20部门一共有多少人
select distinct(count(1)) from emp where deptno in(10,20);

分组

分组: group by , 将符合条件的记录 进一步的分组

过滤组:having, 过滤组信息,表达式同where 一致

现在的结构如下

select distinct * | 字段 | 表达式 | 函数 as 别名
from 表 表别名
where 过滤行记录条件
group by 分组字段列表
having 过滤组
order by 字段列表 asc | desc

解析步骤

  • 1)、from
  • 2)、where
  • 3)、group by
  • 4)、having
  • 5)、select
  • 6)、order by

group by : 分组

1)、select出现分组函数,就不能使用 非分组信息,可以使用group by 字段

2)*、group by字段 可以不出现select中 ,反之select除组函数外的,其他字段必须出现在group by

having : 过滤组

  1. where : 过滤行记录,不能使用组函数
  2. having : 过滤组 可以使用组函数

--按 部门 查询 平均工资
select avg(sal) from emp group by deptno;
--按 部门岗位 查询 平均工资
select avg(sal) from emp group by deptno,job;
--按 部门 查询 平均工资,且平均工资大于2000的部门编号
--1、先分组 后过滤 (不推荐)
select *
from (select deptno, avg(sal) avsal from emp where 1 = 1 group by deptno)
where avsal > 2000;
--2、过滤组 ,分组同时 过滤
select avg(sal), deptno from emp group by deptno having avg(sal)>2000;
--查询 最低平均工资的部门编号
--1)、按部门求出平均薪水
select avg(sal) from emp group by deptno;
--2)、找出最低的平均薪水
select min(avg(sal)) from emp group by deptno;
--3)、过滤组
select deptno
from emp
where 1 = 1
group by deptno
having avg(sal) = (select min(avg(sal)) from emp where 1 = 1 group by deptno);
--查看 高于本部门平均薪水员工姓名
--1、按部门求出平均薪水
--2、关联子查询
select *
from emp e
where exists
(select deptno
from (select deptno, avg(sal) avgsal from emp group by deptno) e2
where e.deptno = e2.deptno
and e.sal > avgsal);
--另外一种 (推荐)
select *
from emp e1
where sal > (select avg(sal) from emp e2 where e2.deptno = e1.deptno);

表链接(99)

交叉连接 cross join --->笛卡尔积

自然连接(主外键、同名列) natural join -->等值连接

join using连接(同名列) -->等值连接

[inner]join on 连接 -->等值连接 非等值 自连接 (解决一切) 关系列必须区分

left|right [outer] join on|using -->外连接

full join on|using -->全连接 满足直接匹配,不满足 相互补充null ,确保 所有表的记录 都至少出

现一次

DDL

SQL语言结构:

DDL(Data Definition Language 数据定义语言)用于操作对象对象的属性,这种对象包括数据库本身,以及数据库对象,像:表、视图等等,DDL 对这些对象和属性的管理和定义具体表现在 create、 drop 和 alter 上。特别注意:DDL 操作的“对象”的概念,”对象“包括对象及对象的属性,而且对象最小 也比记录大个层次。以表举例:create 创建数据表,alter 可以更改该表的字段,drop 可以删除这个表,从这里我们可以看到,DDL 所站的高度,他不会对具体的数据进行操作。

语句

作用

create

可以创建数据库和数据库的一些对象

drop

可以删除数据表、索引、条件约束等

alter

修改数据表定义及属性

三范式

在设计数据库时,存在行业的标准,这个标准也称为条件,即范式 Normal Form。一般遵循三个条件即可,也就是”三范式”(3NF)。

  • 1NF:是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一 行只包含一个实例的信息。
  • 2NF:是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。如 emp 表中加上了员工编号(empno) 列,因为每个员工的员工编号是唯一的,因此每个员工可以被唯一区分。这个唯一属性列被称为主关键字或主键、主码。同时要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个 新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。即第二范式就是非**主属性非部分依赖于主键。
  • 3NF:必须先满足第二范式(2NF)。3NF 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(deptno)、部门名称、地址等信息。那么员工信息表(emp)中列出部门编号后就不能再将部门名称、部门地址等与部门有关的 信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。即第三范式就是属性不依赖于其它非主属性。

简而言之,最终的目的避免数据重复冗余,1NF-->列不可再分最小原子 (避免重复);2NF-->主键依赖(确定唯一;3NF-->消除传递依赖(建立主外键关联 拆分表);

DML

DML(Data Manipulation Language 数据操控语言)用于操作数据库对象中包含的数据,也就是说操作的单位是记录

DML 的主要语句(操作):

语句

作用

Insert

向数据表张插入一条记录

Delete

删除数据表中的一条或多条记录,也可以删除数据表中的所有记录,但是,它的操作对象仍是记录

Update

用于修改已存在表中的记录的内容

使用场景:

insert

注册

update

修改密码

delete

退出、删除、剔除会员

select

登录,查看会员

事务

事务是指作为单个逻辑工作单元执行的一组相关操作。这些操作要求全部完成或者全部不完成。使用事

务是为了保证数据的安全有效

事务有一下四个特点:(ACID)

    1. 原子性(Atomic):事务中所有数据的修改,要么全部执行,要么全部不执行。
    1. 一致性(Consistence):事务完成时,要使所有所有的数据都保持一致的状态,换言之:通过事务进行的所有数据修改,必须在所有相关的表中得到反映。
    1. 隔离性(Isolation):事务应该在另一个事务对数据的修改前或者修改后进行访问。
    1. 持久性(Durability):保证事务对数据库的修改是持久有效的,即使发生系统故障,也不应该丢失。

Oracle 默认的隔离级别是 read committed。

Oracle 支持上述四种隔离级别中的两种:read committed 和 serializable。除此之外, Oralce 中还定义

Read only 和 Read write 隔离级别。

Read only:事务中不能有任何修改数据库中数据的操作语句,是 Serializable 的一个子集。

Read write:它是默认设置,该选项表示在事务中可以有访问语句、修改语句,但不经常使用。

丢失更新:两个事务同时存储, 一个存储 100 , 一个存储 200,最终可能至存储了 200 或者 100,那

另一个的更新就没成功,即结果不为预想的 300

脏读:事务 T1 更新了一行数据,还没有提交所做的修改,T2 读取更新后的数据,T1回滚,T2 读取的数

据无效,这种数据称为脏读数据。

不可重复读:事务 T1 读取一行数据,T2 修改了 T1 刚刚读取的记录,T1 再次查询,发现与第一次读取

的记录不相同,称为不可重复读。

幻读:事务 T1 读取一条带 WHERE 条件的语句,返回结果集,T2 插入一条新纪录,恰好也是 T1 的

WHERE 条件,T1 再次查询,结果集中又看到 T2 的记录,新纪录就叫做幻读

相关文章:

  • 使用 pushd 和 popd 实现快速切换目录
  • JSONP 教程
  • Oracle数据库dump文件的导入与导出及创建表空间
  • 淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段。
  • 南大通用数据库-Gbase-8a-学习-32-gccli客户端
  • Linux的scp、rsync、以及集群分发脚本、ssh配置免密登录
  • 【计算机视觉 | 目标检测】锚点预匹配(Anchor pre-matching)的理解
  • 智联物联分享之物联网协议MQTT简述,MQTT协议特点
  • Echarts立体柱状图
  • SpringBoot定时任务@Scheduled注解详解
  • Gen-LaneNet论文精读总结
  • Spring Cloud Alibaba全家桶——微服务网关Gateway组件
  • 基于微信PC端小程序抓包方法
  • SQL Server 实现邮件发送功能(配置步骤及存储过程源码)
  • 刘禹锡最经典诗文10首,每一首都是千古名作,读懂受益一生
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JS基础之数据类型、对象、原型、原型链、继承
  • Making An Indicator With Pure CSS
  • vue--为什么data属性必须是一个函数
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 欢迎参加第二届中国游戏开发者大会
  • 每天10道Java面试题,跟我走,offer有!
  • 算法系列——算法入门之递归分而治之思想的实现
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 运行时添加log4j2的appender
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (十一)手动添加用户和文件的特殊权限
  • (转)fock函数详解
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .java 9 找不到符号_java找不到符号
  • .Net IOC框架入门之一 Unity
  • .NET 的程序集加载上下文
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .Net7 环境安装配置
  • .NET开源快速、强大、免费的电子表格组件
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • /var/lib/dpkg/lock 锁定问题
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • ?php echo ?,?php echo Hello world!;?
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [20180224]expdp query 写法问题.txt
  • [Android] Implementation vs API dependency