前言:如果我们要学习SQL语句,我们首先需要了解什么是数据库。下面我将先介绍数据库,然后介绍一些常用的SQL语句。
一、数据库介绍:
1.什么是数据库
数据存储的仓库
- 特点:
长期存储数据;对于数据进行有组织的管理(通过操作指定的语言完成数据的增删改查)
- 数据库分类(按照数据存储格式的不同)
- 关系型数据库(二维表):有行有列,类似于excel
Oracle:主要用于大型项目(银行)
MySQL:主要用于中小型项目(目前应用软件最常见的数据库)
SQL Server、SQLite
- 非关系型数据库
redis(键值对)、MangoDB(文档)、Hbase(分布式)
2.数据库核心要素
- 数据库(数据表的集合,有一个数据库中能够有多个数据表)
- 数据表(数据行的集合)
- 数据列(字段)
- 数据行(一条记录)
3.SQL介绍
SQL:结构化查询语言,通过sql语言可以对数据库进行操作
SQL语言分类:
- DQL:数据查询语言,用于对数据查询(select)
- DML:数据操作语言,对数据进行增加、修改、删除(insert、update、delete)
4.MySQL介绍
1.特点:支持多操作系统,支持多种编程语言、开源、社区版免费
2.组成
MySQL客户端:接受用户输入的SQL语句,以及展示SQL语句的执行结果
MySQL服务:存储数据,执行传入的SQL语句
3.常用数据库编辑工具:DBeaver,navicat
5.数据类型
- 字符串:varchar (varchar(3)表示最多存3个字符)
- 整型:int (无符号:unsgined)
- 小数:decimal (decimal(5,2),表示该字段可以存5位数,整数位3位,小数位2位)
- 时间日期:datetime
6.数据约束
- 默认值:当不填写时使用默认值,填写时使用填写内容
- 非空:此字段不允许填写空值(NULL),空字符串(看起来为空值,实际是””)
- 主键(提高数据查询速度)
- 唯一性:主键值必须是唯一的,不能重复
- 非空性:主键不能为空
- 不变性:主键使用了,不可更改
- 单一性:一张数据表,仅能设置一个主键
- 唯一性(一个表中可以设置多个字段值具有唯一性),此字段值不允许被重复
- 外键(维护两个表之间的依赖关系)
7.工具连接
我们通常使用DBeaver来连接并操作数据库(开源免费)
1.作用:拥有可视化界面,让我们操作数据库以及结果的展示更加的直观
2.必填内容:服务器IP地址,MySQL的端口号,MySQL的用户名和密码
二、SQL语句:
1.命令操作数据库
注:建议使用DBeaver更加便捷
- 查看所有数据库:
show databases;
- 查看当前使用数据库:
select database();
- 创建数据库:
create database 数据库名 charset=utf8;
charset=utf8:防止出现中文乱码
- 删除数据库:
drop database 数据库名;
- 注释快捷键:ctrl+/
2.数据表操作
- 创建表
create table 表名(
id int unsigned primary key auto_increment,
字段名称1 数据类型1,
字段名称2 数据类型2,
字段名称3 数据类型3
);
- 删除表
drop table 表名;
drop table if exists 表名;(判断是否存在表)
3.数据库增删改
- 增
1.全字段添加:
insert into 表名 values(…);
注: 插入字段的值与字段的顺序一致,如果有id为主键且自增,则第一个字段应该为“0”或者“null”
2.选择字段添加:
insert into 表名 (字段1, 字段2, …) values(值1, 值2, …);
注:选择添加字段名称,与之后添加字段值必须一一对应
3.插入多条数据
insert into student values (0,’小周’,19,168.50),(null,’小武’,21,185.03),(null,’小王’,22,170.05);
insert into student (name,age) values (‘小郑’,20),(‘小黄’,20),(‘小牛’,21);
说明:
全量字段添加时,主键值必须有,可以是0或者null(主动按照顺序给予添加) 选择字段添加时,主键值可以不用写,会自动添加
- 删
delete from 表名 where 条件
条件:有条件将满足条件的数据进行删除,无条件将整张表的数据进行删除
说明:使用delete一定是删除部分数据,使用都会带上条件
扩展:三种删除数据的区别
- delete
使用场景:针对表中某一次数据删除,进行使用
delete删除所有数据时,自增长字段不会从1开始
适用场景:编写自动化脚本时,测试数据的初始化、清洗时,需要使用delete语句
- truncate
使用场景:表数据的初始化(用了一段时间后,想要重新开始,需要将表清空)
truncate删除数据时,表结构会保留,自增长字段从1开始,执行效率低于drop命令
- drop
如果想删除表,建议使用drop,且删除数据效率最高
- 改
update 表名 set 字段名1 = 值1,字段名2=值2…where 条件
条件:
- 将表中哪些行的数据进行修改(说明:可有可无)
- 无条件修改整张表,有条件修改部分数据
4.单表查询
1.简单查询
- 查看全部数据:
select * from 表名;
- 选择字段查询:
select 字段1,字段2,… from 表名;
2.起别名
select 别名.字段1,别名.字段2… from 表名 (as) 别名
针对表名起别名,方便之后进行联表查询
针对字段起别名,方便进行中文字段展示
3.去重
- 使用场景:统计该字段不同数据的个数
select distinct 字段1… from表名
- 作用:将该字段重复数据去除,不展示
4.排序
order by 字段名 asc(从小到大)/desc(从大到小)
- 表名 order by 字段名称1 排序方式,字段名称2 排序方式
- 首先按照字段名称的排序方式来完成
- 如果字段1相同,那么按照字段2的排序方式来完成
5.比较运算符
>,<,=,>=,<=,!=
表名 where 字段名称 比较运算符 预期结果
6.逻辑运算符
and,or,not
-
主要作用:一次性处理多个字段的条件
-
and,or:条件的中间
-
not:条件前面
7.空判断
- 判断为空:
字段 is null
- 判断非空:
字段 is not null
8.模糊查询
- 关键字 :
like,%,_
- 语句:
表名 where 字段名称 like "匹配符号,指定查询内容"
9.范围查询
- 关键字:
in(非连续查询)
between…and…(连续查询)
- 语句:
表名 where 字段名称 in(一个又一个非连续范围)
表名 where 字段名称 between 开始范围 and 结束范围
10.聚合函数
- 关键字:
count():查询总记录数
max(字段名):查询最大值
min(字段名):查询最小值
sum(字段名):字段值求和
avg(字段名):字段值平均数
- 语句:
select 聚合函数 from 表名
11.分组查询
-
作用:按照要求将整体的数据,划分为不同的小组,任何针对每个小组,使用聚合函数进行二次数据处理
select 分组字段1,分组字段2 from 表名 group by 字段1,字段2
12.分页
- 关键字:
limit
- 语句:
select * from 表名 limit start,count
- 说明:
- 从start开始,获取count条数据
- start索引从0开始(第一行数据---0)
- 例:
-
获取第三名到第六名学生成绩信息
limit 2,4
-
获取前三名学生信息
limit 0,3(0可以省略)->limit 3
5.联表查询
连接查询
- 内连接:结果为两个表匹配到的数据
- 左连接:结果为两个表匹配到的数据加左表特有的数据,对于右表中不存在的数据进行null填充
- 右连接:结果为两个表匹配到的数据加右表特有的数据,对于左表中不存在的数据使用null填充
1.内连接
- 语句:
select * from 表1
inner join 表2 on 表1.关联字段a = 表2.关联字段b;
- 实现思路:
- 确认是否需要多表操作,如果需要梳理哪些表
- 确认表之间的关联字段
- 例1:查询王昭君的成绩,要求显示姓名、课程号、成绩
- (学生信息表:students,学生成绩表:scores,学号:studentNo,课程号:courseNo,成绩:score)
- 分析1-关联表:学生表,成绩表
- 分析2-关联字段:学生表,成绩表--学号
- select * from students stu
- inner join scores sc on stu.studentNo = sc.studentno
- where stu.name = '王昭君';
- 例2:查询王昭君的数据库成绩,要求显示姓名、课程名、成绩
- select stu.name,cou.name,sc.score from students stu
- inner join scores sc on stu.studentNo = sc.studentno
- inner join courses cou on cou.courseNo = sc.courseNo
- where stu.name = '王昭君' and cou.name = '数据库';
- 例3:查询男生中最高成绩,要求显示姓名、课程名、成绩
- 注:到底使用max还是其他方法?
- select stu.name,cou.name,sc.score,stu.sex from students stu
- inner join scores sc on stu.studentNo = sc.studentno
- inner join courses cou on cou.courseNo = sc.courseNo
- where stu.sex = '男'
- order by sc.score desc
- limit 1;
2.左连接
select * from 表1
left join 表2 on 表1.关联字段a = 表2.关联字段b;
- 例:查询所有学生的成绩,包括没有成绩的学生,需要显示课程名
- (学生信息表:students,学生成绩表:scores,课程信息表:courses,学号:studentNo,课程号:courseNo)
- 分析1-关联表:学生表,成绩表,课程表
- 分析2-关联字段:学生表,成绩表---学号;课程表,成绩表---课程号
- 分析3-找出需要范围大的表:学生表
- select * from students stu
- left join scores sc on stu.studentNo = sc.studentno
- left join courses cou on cou.courseNo = sc.courseNo;
3.右连接
select * from 表1
right join 表2 on 表1.关联字段a = 表2.关联字段b;
4.自关联
- 使用场景:当表存在等级关系时,查询其中数据需要使用自关联
如:省,市,县;总经理,部门主管,组长,组员
- 思路:
- 把一张表当成多张表来使用
- 说明:将表定义为不同的别名
- A表的字段与B表的字段进行关联
-
说明:一定是表中不同的字段
-
例1:查询河南省所有的市
- select * from areas a1
- inner join areas a2 on a1.aid = a2.pid
- where a1.atitle = '河南省';
5.子查询
- 编写思路:从结果倒推条件
- 涉及到表之间的关联,可以使用表连接,也可以使用子查询
- 强调:
- 如果能用表连接,绝对不用子查询(子查询SQL语句执行效率很低)
充当条件分类
-
标量子查询:一行一列
-
例1:查询王昭君的成绩,要求显示成绩(标量子查询)
步骤一:获取王昭君的学号
select studentNo from students where name = '王昭君';
步骤二:通过王昭君的学号,获取她的成绩
select * from scores where studentno = (select studentNo from students where name = '王昭君');
-
列子查询:一列多行
-
例2:查询18岁的学生的成绩,要求显示成绩(列子查询)
步骤1:获取18岁学生的学号
select studentNo from students where age = 18;
步骤2:根据18岁学生的学号,获取对应的成绩
select * from scores where studentno in (select studentNo from students where age = 18);
-
行子查询:一行多列
-
例3:查询和王昭君同班且同龄的学生信息(行子查询)
步骤一:通过王昭君,获取年龄和班级
select age,class from students where name = '王昭君';
步骤二:通过获取的年龄和班级,查询数据
select * from students where (age,class) = (select age,class from students where name = '王昭君');
select * from students where age = 20 and class = ‘1班’;
select * from students where (age,class) = (20,1班)
充当数据源
-
先使用内连接将两张表连接成一张表A,然后通过表A进行查询
-
例1:查询数据库和系统测试的课程成绩
步骤1:使用内连接组成一个新表(课程表+成绩表)
select * from courses cou
inner join scores sc on cou.courseNo = sc.courseNo;
步骤2:
select * from (select cou.courseNo,cou.name,sc.id,sc.studentno,sc.score from courses cou
inner join scores sc on cou.courseNo = sc.courseNo) as A
where A.name in ('数据库','系统测试');