sql
structure query language 结构化语言
SQL 是用于访问和处理数据库的标准的计算机语言。
查询
简单查询
语法结构:select 列名 from 表名
关键词:from 确定数据来源
select 确定要获取哪些列
查询部分列
1 | -- 需求:查询员工表中所有员工的工号、名字、工资 |
查询全部列
1 | -- 需求:查询所有员工的所有信息 |
两种方法的优劣:
从实际开发角度:推荐第一种, 获取所有列的次数是很少见;第二种慢,效率低,可读性差
查询结果起别名
语法结构:select 列名1 as 别名1,列名2 as 别名2,列名3 别名3 from 表名
as 可以省略
1 | -- 需求:查询员工表中所有员工的工号、名字、工资,展示效果为工号、名字、工资 |
字符串拼接
语法结构:select 列名1||列名2,列名3 from employees
1 | -- 需求:查询员工表,工号,姓名(first_name||last_name),工资 |
查询结果做算数运算
1 | -- 需求:查询员工的工号、名字、年薪(salary*13) |
去重
概念:如果查询结果中有多行
数据完全一致
,过滤掉重复,只保留一行
语法结构:select distinct 列名,列名 from 表名
关键词:distinct 重复数据
1 | -- 需求:查询员工表中所有的领导 |
排序
语法结构:select 列名 from 表名 order by 列名 asc(升序)|desc(降序),列名 asc|desc
关键词:order by
asc升序 desc 降序
注意:若没有表明desc或asc 默认升序 asc
1 | -- 需求:查询员工表,工号、名字、工资,并且对工资做降序排序 |
子查询
概念:一个查询语句,需要用到另一个查询语句的结果
1 | -- 需求:查询员工表中,工资最高的人的信息 |
子查询结果为一行一列
这种子查询结果,一般作为主查询的条件判断 ,等值判断,或不等值判断
1 | -- 需求:查询员工表中大于平均薪资的员工信息 |
子查询结果为n行一列
这种子查询结果,一般作为主查询的条件判断,枚举
1 | -- 需求:查询员工表中所有和姓为'King'的员工在一个部门的员工信息 |
子查询结果为n行n列
这种子查询结果,一般作为一个临时表,让主查询使用
1 | -- 需求:查询工资最高的前10名员工 |
分页查询
1 | -- 需求:查询第11名到第20名员工信息 |
条件查询
概念:对每一条数据进行条件判断,满足条件放入查询结果
关键词:where 条件
语法结构:select 列名 from 表名 where 条件
等值查询
1 | -- 需求:查询员工表中工资等于17000的员工信息,工号,名字,工资 |
不等值查询 > < >= <= !=
1 | -- 需求:查询员工表中所有工资大于17000的员工信息 |
多条件查询
关键词:or 或 and且
语法结构 where 条件1 or|and 条件2
1 | -- 需求:查询员工表中工资大于10000,并且小于24000的员工信息 |
区间查询
关键词:条件字段 between 起始值 and 结束值
特点:闭区间查询 字段>=起始值 and 字段<= 结束值
语法结构:where 条件字段 between 起始值 and 结束值
1 | -- 需求:查询员工表中工资大于等于10000,并且小于等于24000的员工信息 |
枚举查询
关键词 : in(值1,值2,值3)
语法结构:where 条件字段 in (值1,值2)
1 | -- 需求:查询员工表中90号部门或者100号部门的员工信息 |
模糊查询
关键词:like ‘模糊匹配语法字符串’
模糊匹配:
_:代表任意一个字符
%:代表任意0~n个字符
字符串类型用单引号表示
1 | -- 需求:查询员工表中名字一‘K’开头的员工信息 |
空值(null)查询
关键词:is [not] null
语法结构:where 条件字段 is [not] null
1 | -- 需求:查询出员工表中所有没有提成(commission_pct)的员工 |
分支查询 case when
位置:经常写在select后面
作用:对查询结果进行进一步的处理,以一种符合用户习惯的方式展现
1 | --需求:查询员工表,将工资分为高薪,中等,低薪 |
特殊关键词
sysdate 系统时间 年 月 日 时 分 秒
systimestamp [时间戳] 系统时间 年 月 日 时 分 秒 毫秒
1
2
3
4
5
6
7 >--需求:获取当前系统时间
>select sysdate
>from employees
>select systimestamp
>from employeesdual 虚表 只有一行一列的表,常用于测试
从数据的角度上:没有任何意义
作用:维护Oracle数据库sql语法的完整性
1
2
3 >--需求:获取当前系统时间
>select sysdate
>from dual
函数
概念:具备特定功能的sql命令
函数三要素:返回值类型、函数名、参数列表
函数分类:单行函数、组函数
单行函数
特点:每处理一行数据,都会有一个返回结果
107行 —–单行函数—-》107个结果
length(‘字符串’)
计算字符串的长度
1 | -- 需求:计算'abcdefgdfdf'的长度 |
to_date(‘字符串类型的日期’,’日期转换格式’)
把字符串类型的日期,转换为日期类型
1 | -- 需求:将’2020-10-23‘转换成日期格式 |
to_char(日期类型的日期,’日期转换格式’)
将日期类型转换成字符串类型
1 | -- 需求:将当前系统时间转换成字符串 |
mod(被除数,除数)
求余数
1 | --需求:求余数 |
nvl(x1,x2)
如果x1是null,就是返回x2,不是null,返回本身
1 | -- 需求 |
小总结
关键词:
1
2
3
4
5 >from 确定数据来源的表
>where 筛选出满足条件的数据
>select 确定获取哪些列数据
>order by 根据某一字段对查询结果进行排序
>distinct 过滤重复数据语法结果:select … from … where … order by
执行顺序:from where select order by
组函数
特点:每一组只有一个返回结果
作用:对已经确定
的表或组
进行数据统计、分析
where后面不能使用组函数
组函数不对null进行任何统计处理
若使用组函数,select 后面只能写组函数
常用的组函数
count(字段) 统计有效行数
max(字段) 最大值
min(字段) 最小值
avg(字段) 平均值
sum(字段) 求和
1 | -- 需求:统计员工表中有提成员工的个数 |
分组
关键词:group by 字段 根据字段进行分组
语法结构:select … from … where … group by … order by
补充:分组之后,select后面能写组函数以及分组依据字段
1 | -- 需求:统计员工表中每个部门的人数 |
分组过滤
关键词:having 对分组之后的数据进行筛选,过滤
语法结构:select … from … where … group by … having … order by
1 | -- 需求:查询部门平均薪资大于9000的部门id以及平均薪资 |
where是在分组前过滤数据
having是在分组后过滤数据
当两种方法都能解决问题,优先使用where
伪列
概念:建表时,不存在的列,但是,查询时,可以查到
分类:rowid和rownum
rowid
概念:一行数据存在硬盘的物理地址,可以唯一标示一行数据
物理地址:一行数据在硬盘上的具体位置
1 | -- 需求:查询员工表中员工信息,工号,名字,salary,物理地址(rowid) |
rownum
概念:对查询结果做一个编号(从1开始,依次递增)
特点:
- 从1开始,依次递增
- 对满足where条件的数据进行编号
- rownum做比较时,< <= >=1 =1
1 | -- 需求:查询所有员工信息,做rownum |
表连接
根据连接条件,将多张表连接成一张表,放在from后面使用
内连接
关键词:[inner] join
语法:表1 [inner] join 表2 on 表1.字段n = 表2.字段n
1 | -- 需求:查询员工信息,工号,名字,工资,部门编号,部门名称 |
特点:
- 将左表与右表中互相对应的数据连接到一张表里
- 若左表存在,右表中没有与之对应的数据,直接舍弃
外链接
左外链接
关键词:left [outer] join
语法:表1 left join 表2 on 连接条件
1 | -- 需求:查询员工信息,工号,名字,工资,部门编号,部门名称 |
特点:若左表存在,右表中没有与之对应的数据,保留,右表缺失的数据补空
右外链接
关键词:right [outer] join
特点:若右表存在,左表中没有与之对应的数据,保留,左表缺失的数据补空
完整外链接
关键词:full [outer] join
特点:无论是否有对应数据,统统保留
表连接应用
1 | -- 需求:查询部门信息:部门编号,部门名称,部门所在地标号,部门所在城市 |
建表
一张表里面包含哪些东西?
表名 必须
字段名 必须
数据类型 必须
约束 进一步限制了字段中值的内容 不必须 根据需求建表语法:
create table 表名(
字段名 数据类型 [约束],
字段名 数据类型 [约束],
…..
字段名 数据类型 [约束]
)
修改表结构:
alter table 表名 add 字段名 数据类型 [约束]-----给已经存在的表增加新的字段
alter table 表名 drop column 字段名-----删除表中已经存在的字段
删表:drop table 表名
数据类型
数字类型
number(n) 整数 最大长度为n
number(n,m) 小数 n是总长度,m是小数部分长度 整数部分长度为n-m
如果小数部分长度没有达到m,后面补0,支持四舍五入
integer ,double—已过时,不建议使用
字符串类型
char(n) 定长字符串 数据长度不够n,以空白字符填充 ‘abc ‘
varchar2(n) 可变长字符串 数据长度不够n,那就算了,不填充空白字符
日期类型
date 包含年月日时分秒
大文本类型
clob varchar2最大能存4000个字符
约束
主键约束(primary key)
唯一标示一行数据 唯一+非空
应用场景:工号,学号,编号...
唯一约束(unique)
值唯一,不能重复
应用场景:手机号,身份证号,邮箱....
非空约束
语法:not null 值不能为空
应用场景:名字,年龄....
检查约束
语法:check(约束语法)
应用场景:
银行卡密码:check(length(字段名)=6)
邮箱:check(字段名 like '%@qq.com')
外键约束(foreign key)
语法:references 表名(主键字段名)
关键词:references 指向,引用
作用:从数据角度上给两张表建立一个连接关系
特点:子表中加了外键约束的字段中的值,必须从指向主表中的主键列中获取,或者 为null
例子:学生表(t_stu)中有class_id references t_class(class_id),班级表(t_class)中也有class_id primary key
存在外键约束的表称之为子表,外键指向的表称之为主表
注意:先建主表,后建子表 先删子表,后删主表 先往主表中添加数据,在往子表中添加数据
1 |
|
增删改操作
添加数据(增)
语法: insert into 表名 (字段名1,字段名2,字段名3…) values (值1,值2,值3,….)
关键词: insert into…. values
values后的值的顺序要和表名后字段名的顺序保持一致
表名后的字段可以省略,此时Oracle默认全部字段添加,并且按照建表时的字段顺序,添加值
1 | -- 需求:向班级表中添加一行数据 |
删除操作(删)
语法: delete [from] 表名 [where条件]
特点:逐行删除满足条件数据
注意:若不加where条件,会将全表的数据都给删掉,表还存在
1 | -- 需求:删除学生表中的学号为1的学生信息 |
补充:
表截断:实际上也是删除表中的数据
语法: truncate table 表名
特点:是直接从表的实际存储位置上,将表的数据部分截断并丢弃
优点:效率快
修改操作(改)
语法:update 表名 set 字段1 = 新值1,字段2 = 新值2[where 条件]
注意:若不添加where条件,会将全表的相应字段都做修改
1 | -- 需求:将学生表中学号为3的学生名字改为‘程某’ |
sql分类
ddl:数据定义语言 create alter drop
dml:数据操作语言 insert delete update
dql:数据查询语言 select
tcl:事务控制语言 commit rollback
事务
问题:银行存钱,取钱,转账业务怎么实现
银行用户表:bank_account
id name cardid password balance 1 黄亮 1001 123456 10000 2 大漂亮 1002 654321 5000
1
2
3
4
5
6
7
8
9
10 >-- 转账:黄亮为了避免一个人过‘光棍节’,需要给他女朋友大漂亮资助9998过劫费
>-- 第一步:先将黄亮账户余额减去9998
>update bank_account set balance = 2 where cardid = 1001and password = 123456
>-- 第二步:再将大漂亮账户余额加上9998
>update bank_account set balance = 14998 where cardid = 1002 and password = 654321
>-- 可能发生意外情况:导致第一步执行成功,但是第二步执行失败
>-- 希望情况:要么两步都执行成功,要么都执行失败
>-- 总结:将实现一个功能的所有sql语句当成一个整体,要么全部执行成功,要么全部执行失败--事务概念:数据库中的dml语句的最小执行单元,将多个sql当做一个整体
特点:要么全部执行成功,要么全部执行失败
事务的使用:
1.成功结束事务:commit(提交)
2.失败结束事务:rollback(回滚)
事务的实现简单步骤
数据库会为每一个客户端都分配一个回滚段(临时空间 rollback seagment),回滚段中存储着当前客户端的数据处理结果
commit(提交),将回滚段中的结果同步到数据库当中
rollback(回滚),将回滚段中的结果丢弃
事务的边界
事务的开启时机:
- 上一个事务结束
- 执行dml语句
事务的结束时机
提交:
commit
正常退出客户端
执行ddl语句的时候
回滚:
rollback
非正常退出
eg:
1
2
3
4
5
6
7
8
9
10
11
12 >--问题:以下操作,有几个事务
>insert
>insert
>commit
>select
>rollback
>update
>delete
>commit
>delete
>rollback
>--总共三个事务,两次提交,一次回滚
事务的特性ACID
原子性:一个中的多个sql语句,要么全部执行成功,要么全部执行失败
一致性:一个事务的结束(成功或失败),数据的修改是一致的,合理的
隔离性:一个客户端的事务结束前,其他客户端事务不可见
持久性:事务的结束(无论成功或失败),对于数据的影响是永久的
序列
概念:Oracle自带的一个工具,可以自动生成一系列连续不重复的值
应用:添加数据时,作为主键的值
创建序列:create sequence 序列名 [start with 值]
使用序列:
- 序列名.nextval 获取到序列中下一个值
- 序列名.currval 获取序列当前的值
1 | -- 应用:创建序列,获取序列中的值 |
删除序列:drop sequence 序列名
视图
语法:create view 视图名 as select语句
概念:将一个select语句的查询结果,当做一个视图(一个虚拟的表),供后来查询使用
1 | -- 视图的使用 |
优点:
- 简化sql语句
- 对部分开发人员屏蔽掉表名及字段名关键信息
注意:
- 视图能够提高查询效率——错误
删除视图:drop view 视图名
索引
问题:当Oracle数据库中的数据量达到1000万,查询效率就会直线下降
当查询数据时,会对全表中的所有数据都进行筛选,找出符合要求的数据。如果我们能够对数据库创建出一个类型图书目录的结构,这个结构就是索引
概念:类似图书目录的结构,提高查询效率
创建索引:create index 索引名 on 表名(字段名)
相当于:create index 目录名 on 西游记(章节名)
删除索引:drop index 索引名
使用索引:不需要手动使用,当以索引字段进行查询时,会自动使用索引,提高查询效率
索引的特点:
- 索引会占用硬盘空间
- 索引会降低dml操作的效率
- 只有以创建索引的字段为查询条件时,才会提高查询效率
- 主键约束和唯一约束的字段,会被默认添加索引