目录
一、认识数据库
1. 什么是数据库
2. 数据库类型
3. 常见的数据库管理系统
4. MySQL介绍
5. MySQL的安装&管理工具的安装
6. SQL概述
7. 在DOS系统中操作MySQL
8. MySql常用命令
二、操作数据库
2、备份和还原数据库
3、MySQL数据类型
4、使用SQL语句创建表
5、 数据完整性
6、 表的管理
三、MySQL的数据操作
1.MySQL条件表达式和逻辑表达式
2.INSERT插入语句
3.DELETE/TRUNCATE删除语句
3.1 Delete语句
3.2 Truncate语句
3.3 三个删除的区别
4. UPDATE修改语句
5. 简单查询
6.CASCADE级联问题
6.1、问题阐述
6.2、解决办法
6.3、图形界面操作
6.4、SQL命令完成级联操作
四、 数据查询
一:查询的概述
1.1、Limit查询
1.2、Distinct去重
1.2、Where子句
1.3、查询结果排序
二:MySQL 内置函数
2.1、字符串函数
2.2、日期函数
2.3、数学函数
2.4、系统函数及其它
小结
五、 模糊查询与分组查询
案例用表
一:模糊查询
1.1、%通配符
1.2、_单个字符
1.3、转义字符 Escape
1.4、正则模式
1.5、Between运算符
1.6、IN运算符
二:聚合函数
三:分组查询
3.1、单列分组查询
3.2、多列分组查询
六、多表数据连接查询
一、必要性
二、多表连接查询
2.1、交叉连接
2.2、内连接
2.3、外连接
三、联合查询union
3.1、合并查询结果
3.2、Union 与 Join 的区别
四、子查询
4.1、基本子查询
4.2、高级子查询
从数据管理角度分析,数据库的发展可以分为三个阶段:
人工管理阶段 20世纪50年代中期之前
文件系统阶段 20世纪50年代中期到60年代中期
数据库系统阶段 20世纪60年代后期
先来认识几个概念:
数据和数据库:
数据(Data):是关于自然、社会现象和科学试验的定量或定性的记录,数据是所有计算机系统所要处理的对象。比如声音、图像,称为模拟数据。符号、文字,称为数字数据。
数据库(DataBase):在计算机体系内,简单来讲就是存储数据的“仓库”,是按照数据结构来组织、存储和管理数据的仓库。简称为DB。通常是一个或一组文件,保存了一些符合特定规格的数据,数据库软件称为数据库管理系统DataBase Management System(DBMS):数据库的运行管理系统。
数据库系统(DBS):数据库、数据库管理系统、应用系统、数据库管理员和用户构成。
实体和属性(数据表):
表(table)是一种结构化的文件,可用来存储特定类型的数据。
表都有特定的名称,同一个数据库中表名不能重复。
实体和属性是面向对象的概念,分别对应 “记录”和 “字段”
实体(行/记录):是客观存在并可以相互区别的事物,对应数据表中的一行“记录”
属性(列/字段):是事物本身固有的性质,对应数据表中的“字段”或“列”
数据表与数据库
数据表就是记录的集合 。
数据库就是数据表、数据库关系和数据库关系对象的集合
数据除了可以存放在数据库中,我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢,所以现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量。
数据库可以分为关系型数据库和非关系型数据库。
所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
RDBMS即关系数据库管理系统(Relational Database Management System)的特点:
· 数据以表格的形式出现
· 每行为各种记录名称
· 每列为记录名称所对应的数据域
· 许多的行和列组成一张表
· 若干的表组成database
关系型数据库:表与表之间存在对应关系。
非关系型数据库:表之间不存在关系,数据独立,随便存。
oracle:在全球范围内市场份额占据32%
sql server: 在我国,.net平台和sql server数据库应用也极其广泛
Sybase: 广泛应用于我国的大中型应用软件中
IBM/DB2:在OS/2和windows系统中应用广泛
mysql:简单,开源,功能强大
国产数据库:以南大通用大数据新型列存储数据库(GBase)、人大金仓通用关系型数据库(KingbaseES)、华为关系型数据库系统GaussDB(openGauss,开源数据库)为代表。
非关系型数据库:也称为NoSQL(Not only SQL),是一种不同于关系型数据库的数据库管理系统设计方式,是对非关系型数据库的统称。常见的有MongoDB、HBase、Redis、MemCache等。
MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。由瑞典MySQL AB公司开发,目前属于Oracle公司。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
Mysql是开源的,所以你不需要支付额外的费用。
Mysql运行速度快,检索高效,服务稳定,很少出现异常宕机,性能卓越。
支持Linux、Windows、MacOS等多种操作系统。
MySQL使用标准的SQL数据语言形式。
Mysql可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
MySQL支持大型数据库,支持5000万条记录的数据仓库,可以处理拥有上千万条记录的大型数据库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。
MySQL数据库的安装,无脑下一步。参考安装步骤。
管理工具选择使用:Navicat。
SQL(Structured Query Language),即结构化查询语言,是高级的非过程化编程语言。SQL是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系型数据库系统。
SQL同时也是数据库文件格式的扩展名。
sql用来和数据库打交道,完成和数据的通信。SQL语言集数据查询(Data Query)、数据操纵(Data Manipulation)、数据定义(Data Definition)和数据控制(Data Control)功能于一体。
1986年10月,美国国家标准协会对SQL进行规范后,以此作为关系式数据库管理系统的标准语言。Sql成为一套国际标准,不过各种不同的数据库系统在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL不能完全相互通用
首先进入mysql安装目录下的bin目录下:
输入cmd,进入MySQL数据库: mysql -h localhost -uroot -p
-h 服务器(本地、指定服务器IP的)[本地localhost可以省略]
-u 用户名(我们用的是root用户:超级管理员)
-p 用户密码(不需要再它后面写密码,密码是回车之后写的)
show databases;
显示当前所有数据库
use mysql;(mysql指数据库名)
指定使用哪一个数据库
show tables;显示当前数据库内所有的表名
desc users[表名];查看当前数据表的结构
在数据库连接中,默认的数据库:
information_schema:提供了访问数据库元数据的方式。
mysql:是mysql的核心数据库。
performance_schema :主要用于收集数据库服务器性能参数。
test : mysql创建的测试库。
create database [database_name];
drop database 数据库名;
show databases;
use 数据库名;
select database(); -- 显示当前所使用的数据库
show create database 数据库名; -- 查看这个数据库的建库语句;
show create table 表名; -- 查看这个表的建表语句 desc 表名; -- 查看表结构
# 创建表: create table 表名( • 字段名 类型(长度) [一堆约束……], • …… );
字符集是自然语言字符集合及其在计算机中的编码和字符串排序规则。每个字符集至少对应一个排序规则。
常见字符集
计算机系统存在大量字符集,常见的有:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集、UTF-8字符集等。其中:
Unicode支持现今世界各种不同语言的书面文本的交换、处理以及显示,以满足跨语言、跨平台进行文本交换、处理的请求。
UTF-8(8-bit Unicode Transformation Format)是Unicode的其中一个编码格式,是把Unicode字符集按某种格式存储,采用可变长度字节来储存Unicode字符。UTF-8是一种针对Unicode的可变长度字符编码,又称万国码。
MySQL支持多种字符集,默认使用是UTF-8,可以设置不同级别的字符集:服务器级、数据库级、数据表级、字段级。
查看当前MySQL系统支持的字符集:
show character set
查看当前服务器级字符集:
show variables [like 'character_set_server']
查看当前数据库级字符集
show variables like 'character_set_database'
查看字符集排序规则
show collation [like 'charset_name% ]
中括号【】包含内容是可选项。不写的时候是查看全部排序规则,写上的时候可以按指定的字符集名称匹配的方式查找字符集排序规则。‘%’是模式匹配符号,只要字符集是%前指定字符串开头的,都会显示比如:show collation like'utf8%'
l 启动服务
用命令行的方式启动 net start mysql57
打开windows+r,输入services.msc 找到MySQL的服务,右键启动。
语法:
create {database|schema} [if not exists] db_name [default] character set [=] charset_name | [default] collate [=] collation_name
语法说明:
create database db_test default character set=GBK
先建立连接:
创建数据库:
不需要的数据库,右键删除即可。
MySQL提供多种存储引擎,这是区别于其他DBMS只有一种存储引擎的特点。
存储引擎是MySQL数据库的重要组成部分,规定如何存储表数据、索引、是否支持事务、以及更新、查询数据等技术的实现方法。存储引擎也成为表类型。不同于Oracle、SQL Server等数据库只用一种存储引擎,MySQL数据库提供了多种存储引擎,用户可以根据业务需求,为表数据选择适用于专门检索数据还是适用于事务处理的存储引擎,使得服务器性能处于更佳状态。
查看MySQL所有存储引擎:
show engines;
InnoDB是MySQL5.5版本及以上默认使用的存储引擎,之前的版本是MyISAM存储引擎。
InnoDB存储引擎
InnoDB是唯一支持事务的MySQL存储引擎。由甲骨文公司开发。目前已被雅虎、谷歌等公司采用。
特点:
InnoDB提供了事务、回滚、修改能力,也是第一个提供外键约束的存储引擎。
MyISAM存储引擎
是使用InnoDB以前MySQL的默认存储引擎.基于ISAM并进行扩展,具有较高的插入和查询速度,但不支持事务和外键约束。
优势是:占用空间小,处理速度快。
MEMORY存储引擎
通过存储内存数据表来访问数据,使用内存来创建存储数据表,类型为.frm的磁盘文件只用来存储表结构,能够快速处理数据,但需要足够的内存空间,一旦宕机数据将全部消失。
特点:将数据存储到内存,数据处理速度快,但不安全。对数据表大小有要求,太大的表则无法使用此存储引擎。
选中要备份的数据库--->右键--->转储SQL文件--->结构和数据:
成功则可以生成一个sql文件。如果数据库中没有名字为ktv的数据库,就可以在数据库执行ktv.sql文件,可以直接生成该数据库,并带有数据。
数据类型用于规定数据的存储格式、约束和有效范围。
MySQL提供的数据类型主要包含:数字类型(整数类型、浮点数类型和定点数类型)、字符串类型、日期和时间类型以及JSON类型。
数值类型
MySQL支持所有ANSI SQL-92标准数字类型:精准数字类型NUMERIC、DECIMAL(DEC)、INTEGER(INT)和浮点数字类型(float、double、real)
定点数类型(numeric、decimal、dec)用来存储小数位精准的数字数据。可以做等值比较,一般用于财务数字类型。
字符类型
包含普通文本字符串类型(char、varchar)、大文本字符串类型(text)、二进制字符串类型(blob)和特殊类型(set多选项数据类型、enum单选项数据类型)。
日期类型
表示时间值的日期和时间类型为datetime、date、timestamp、time和year。
每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。
二进制类型
-- 创建数据库 CREATE database 2202_project; -- 改变当前使用的数据库 use 2202_project; -- 创建数据表 student create table student( sid int(10) PRIMARY KEY auto_increment, -- 学生编号 类型 主键 自增 sname varchar(20) unique , -- 学生姓名 唯一 age int(10) not null, -- 年龄 非空 classId int , -- 所在班级号 需要加外键约束 constraint fk_stu_class FOREIGN key(classId) REFERENCES class(classId) ); -- 此时因为班级表class不存在,所以外键约束添加错误。执行不成功。所以需要先创建班级表! # 班级表 CREATE TABLE class( classId int PRIMARY key auto_increment, className varchar(10) not null, beginTime datetime not null, endTime datetime , gradeId int not null ); -- 删除数据表 drop table student;
数据完整性(Data Integrity)是指数据的精确性(Accuracy)和可靠性(Reliability)
数据完整性分为4类:
Ø 实体完整性(Entity Integrity)
实体完整性将行定义为特定表的唯一实体,它规定表的每一行记录在表中是唯一的。
实体完整性在表中的约束体现为:
约束 | 含义 | 描述 |
---|---|---|
PRIMARY KEY | 主键约束 | 主键是表中一列或多列数据,用来唯一标识一行数据。例如:学号主键必须不为空 |
AUTO_INCREMENT | 自增约束 | 使列值自增,一般用来做主键使用。auto_increment表示第一行记录的列值为1,第二行的值为2。以后每次加1,不需要用户显式地添加数据 |
UNIQUE | 唯一约束 | 可以用来确保在非主键列中不存在重复值,但列值可以是NULL(空)。 |
Ø 域完整性(Domain Integrity)
域完整性(Domain Integrity)是考虑如何限制向表中输入的值的范围
域完整性的约束:
DEFAULT(默认值)约束
NOT NULL(非空)约束
Ø 引用完整性(Referential Integrity)
外键约束:是在插入或删除数据时,维护表间数据一致性的关系,是建立在主键的基础之上的
外键约束语法:
constraint 约束名称 foreign key(外键列--本表) references 关联表(关联表的主键)
注意:
本表外键列必须和关联表的关联列(主键)数据类型必须一致。
本表中外键列中录入的值必须在引用表中存在,否则不能录入
如果已经被引用过的数据,不能被删除
MySQL支持的约束类型包括以下几种:
任务练习 1:
-- 建表之前先检查数据库,不能使用系统数据库。 可以自己创建一个数据库 create database if not exists db_test; -- 创建数据库 use db_test; -- 使用指定数据库 # 创建顾客表 create table customer( id int auto_increment primary key, -- 主键 customer_name varchar(20) not null, -- 顾客姓名 sex enum('男','女')null default '男', -- 性别(单选项) identity_id char(18) null, --身份证号 birthday date null, -- 生日 hobby set('唱','跳','rap'), -- 爱好,多选项 -- 消费金额总长度11为,小数点后二位数,unsigner表示无符号,即当前数据只能是非负数 consumption_amount decimal(11,2) unsigned null default 0.00, menber_balance decimal(11,2) unsigned null default 0.00, -- 会员余额 photo varbinary(250) null, -- 头像照片 address json null -- 地址 JSON类型 )engine =InnoDB character set=utf8mb4 collate =utf8mb4_0900_ai_ci row_format =Dynamic; -- engine =InnoDB : 设置引擎为 InnoDB -- character set=utf8mb4: 字符集设置 -- MySQL在5.5.3版本之后增加了这个utf8mb4的编码,mb4就是most bvtes 4的意思, -- 专门用来兼容四字节的unicode。其实,utf8mb4是utf8的超集并完全兼容utf8, -- 能够用四个字节存储更多的字符理论上原来使用utf8,然后将字符集修改为utf8mb4, -- 也会不会对已有的utf8编码读取产生任何问题。但是一般为了节省空间,使用utf8就够了。 -- MySQL里实现的utf8最长使用3个字节,但是现在生活中手机常用的表情字符emoji -- 还有一些不常用的汉字,如 别墅的“墅”,这些需要四个字节才能编码出来, -- 所以就需要utf8mb4。 -- collate =utf8mb4_0900_ai_ci是MySQL数据库中用于指定字符集和排序规则(colation) -- 的一个字符串。其中,utf8mb4代表采用的字符集,0900代表Unicode版本, -- ai表示采用根据语音和字符的颜色进行排序的规则,ci表示不区分大小写。 -- 该字符串经常用于创建MVSQL数据库表时指定列的排序规则。 -- row_format = dynamic 是 MySQL 中用于设置表格行格式的一种造的格式。 -- 当使用"row format= dynamic"时,MySQL 会自动根据每一行的际长度选择 -- 最适合的行格式,可以是"fixed"、"dynamic"或compressed -- 插入一条数据 insert into customer (id,customer_name,sex,identity_id,birthday,hobby, consumption_amount,menber_balance,address) values (1,'张三','男','425568200001021234','2000-01-02','唱,跳', 8888,0.00,'{"省份":"河南","城市":"郑州","地区":"二七"}');
任务练习 2:
-- 建表之前先检查数据库,不能使用系统数据库。 可以自己创建一个数据库 use db_test; -- 使用指定数据库 -- 建立部门表 department create table department( id int auto_increment not null primary key , -- 主键 dept_name varchar(20) not null unique , -- 部门名称,唯一 dept_phone char(13), -- 部门电话 dept_memo varchar(100) comment '部门备注' -- 部门描述信息 ); -- 使用默认引擎字符集 -- 创建职员表 create table staffer( id int auto_increment not null, -- 编号 username varchar(32) not null, -- 职工账号 password varchar(32) not null, -- 密码 dept_id int not null, -- 所属部门ID staff_name varchar(10) not null, -- 职工姓名 sex enum('男','女') default '男', -- 性别 birthday date , -- 生日 phone char(11), -- 电话 salary decimal(8,2) unsigned default 0.00, -- 薪资 staff_memo varchar(100), -- 职工备注信息 primary key(id) , -- 设定主键 unique(username), -- 设定唯一键 foreign key(dept_id) references department(id), -- 设定外键 check(salary>=0 and salary<100000) -- 自定义检查约束,限定薪资范围 -- check约束在MySQL8.0.16版本有效,之前的版本忽略,无约束效果(但解析可以通过)。 )
Ø 添加字段
-- 语法解析: -- alter table 表名 add) column 列名 列类型 约束 alter table employee add column mgr int not null
Ø 删除字段
-- 删除字段 alter table employee drop column mgr;
Ø 删除外键约束
-- 删除外键约束 alter table employee drop foreign key fk_emp_dept;
Ø 添加外键约束
-- 添加外键约束 alter table employee add CONSTRAINT fk_emp_dept foreign key(deptno) REFERENCES dept(deptno)
Ø 修改字段
-- 修改字段 alter table employee change column job job2 varchar(10) default '职员'
Ø 复制数据表
-- 复制一张student表 -- 使用like方式 create table if not exists stu1 like student; -- 使用as方式 create table if not exists stu2 as select * from stuednt;
表达式是指使用运算符将同类型的数据(如常量、变量、函数等)按一定的规则连接起来的,具有特定意义的语句。
MySQL中表达式包括:
条件表达式 (3>2)
逻辑表达式 (3>2 && 3>4)
这两种表达式结果只能为TRUE或FALSE。
SQL命令支持的逻辑运算符有 And 、Or 和 Not。
And和Or运算符连接条件,Not否定条件。
当语句中使用了多个逻辑运算符时,运算时先求Not的值,然后求And的值,最后再求Or的值。
INSERT 语句用来往数据库中添加数据,可以一次添加一行或者多行数据数据
语法:
INSERT [INTO] table_name [(COLUMN1 [,COLUMN2 [,......]])] VALUES (VALUE1 [,VALUE2 [,......]);
table_name:表名
COLUMN:列名(字段名)
VALUES:需要添加到数据表的值
INTO:关键字,可以省略
-- 插入单条语句 insert into student(sname,age,sex,birthday) values('张三',18,'男','2000-03-05'); -- 插入多条语句 insert into student(sname,age,sex,birthday) values ('刘备',18,'男','2000-03-05'), ('关羽',18,'男','2000-03-05'), ('张飞',18,'男','2000-03-05'), ('赵云',18,'男','2000-03-05');
注意:
添加数据时,如果字段类型为varchar或date,必须使用单引号('2023-06-05')引起来
添加记录但不指定所有字段值,不指定字段时,该字段必须是允许为空。
有默认值约束的列不指定值时将使用默认值。
主键列、唯一约束列的值不能重复。
值与字段名必须一一匹配,但是可以不按照表中字段顺序指定。
添加记录时自增的列不需要显式地添加
表中每列数据都添加值时字段名可以省略
delete 删除表中数据。
语法:delete from 表名 [where 字段名=?]
# 删除整张表 delete from student; # 删除指定记录 -- 删除编号为1的学生信息 delete from student where sid=1; -- 删除姓名是jack并且是男性的学生信息 delete from student where sname='jack' and sex='男'; -- 删除所有班级是1和2的学生信息 delete from student where classId in (1,2);
truncate 清空整张表的数据,重置。
# 清空整张表 truncate table student;
语句 | 优点 | 缺点 |
---|---|---|
delete | 选择性地删除数据,可以返回行数。 | 当删除整张表的数据时效率较低。删除自增列不会重新编码 |
truncate | 只能删除整张表的数据,但是效率高于使用DELETE语句。 | 不能选择性删除。自增列会重新编码排序。 |
drop | 删除数据表、删除数据库 | 不能操作数据。 |
UPDATE语句用于修改表数据。
语法:
UPDATE table_name SET COLUMN1={}, COLUMN2={}...... WHERE<表达式>
案例:
-- 修改整张表中age的值为20 update student set age=20 -- 修改编号为3的学生年龄为22 update student set age=22 where sid=3 -- 修改编号为5的学生 年龄为26,地址为北京 update student set age=26 , addr='北京' where sid=5 -- 修改 班级号是3 或者 名字是李四的人的性别为女。 update student set sex='女' where sname='李四' or classid=3
-- 查询全表 selct * from student -- 查询指定列 select sname,age,birthday from student -- 查询 编号为6的学生的所有信息 select * from student where sid =6 -- 查询指定字段,并以 别名 为 字段名显示。 select sname as 姓名,sex as 性别 , age 年龄 from student -- as起别名,可以省略不写 -- 查询年龄大于18的学生姓名和地址 select sname,addr from student where age>18 -- 查询年龄大于18的女孩子的姓名 和 班级编号 selects sname,classid from student where age>18 and sex='女'
当两个表存在主外键关联关系的时候,对主表中的主键信息进行修改、删除操作,外联表中存储与其相对应的外键信息也应该同步的修改。
比如:学生表和班级表有外键关联关系。
这时候删除某一个班级就会执行不成功,如下图所示:
delete from classinfo where classid=1
由于classinfo表被student表所引用,在删除或者修改时都会报错。因为违反了数据完整性中引用完整性和域完整性。
第一种:
可以在先删除或者更改外键信息的前提下,再删除或者修改该主键信息,就可以正常执行。
缺点:
如果表的主键信息被多个表所引用,那么操作将是非常繁琐的,这个时候就不能通过这个方法来实现数据的完整性。
第二种:
MySQL提供了一种叫级联(CASCADE)的方式,当主键的信息删除或者修改时,引用的外键信息就会对应的删除或者修改。
在Navicat中选中表,右键----->设计表----->
在删除时和更新时的下拉框中选择CASCADE,然后保存即可。
如果要操作的表在之前创建的时候,已经创建好了外键约束,
则需要先删除之前的外键约束然后再添加带级联操作的外键约束。
# 先删除旧有外键约束 alter table student drop foreign key fk_约束名字; # 重新添加外键约束 alter table student add constraint fk_约束名字 foreign key(classId) references Classinfo(classId) ON DELETE CASCADE #打开级联删除 ON UPDATE CASCADE; #打开级联更新
对数据表中现有数据的筛选,按照要求把符合查询的条件的记录的指定的字段值提取出来,形成一个新的表,把结果呈现给用户。
查询的语法结构:
SELECTFROM [WHERE <表达式>] [ORDER BY < Column1, Column2……>[ASC或DESC]]
示例:
-- 语法 SELECT 姓名 , 年龄 , 工作地点 FROM studentInfo WHERE 工作地点 = '上海'; -- 案例: USE SchoolDB; -- 选择要使用的数据库 SELECT * FROM StudentInfo; -- 查询表中全部数据
MySQL对大小写不敏感,包括关键字在内。
使用LIMIT限定查询返回行: LIMIT 子句用于限制SELECT 语句返回指定的记录数。
语法及案例:
# 语法 : 从a开始,查询b条 select * from student where limit a,b
查询出表的前3行数据。
select * from book limit 3
获取 [从第2行开始,取出3条] 学生信息。
select * from book limit 1,3
去除重复行:对返回结果中重复的值进行去重。
select DISTINCT author from book
单条件查询
-- 要求查询年龄在20岁以上的学生信息 。 SELECT * FROM StudentInfo WHERE Age > 20;
多条件复合查询
-- 查询出年龄为20岁的女生信息 SELECT * FROM StudentInfo WHERE Age=20 AND Gender ='女'; -- 查询出家不在郑州的年龄或者年龄不到20岁的学生信息 SELECT * FROM StudentInfo WHERE Age<20 OR City <> '郑州'; -- 查询出不是1班的学生信息 SELECT * FROM StudentInfo WHERE NOT ClassID = 1;
Ø 单列排序
单列排序是按照某一列升序或降序排列,即ORDER BY子句后面只有一个字段。
示例:
-- 1.按照学生的年龄以升序进行排列查询。 SELECT * FROM StudentInfo ORDER BY Age ASC; -- 2.按照学生的年龄以降序进行排列查询。 SELECT * FROM StudentInfo ORDER BY Age DESC;
Ø 多列排序
示例:
-- 查询所有学员的信息。按照 年龄降序进行排列和 出生日期的升序进行排列 。 SELECT * FROM StudentInfo ORDER BY Age DESC,Birthday ASC;
函数名 | 示例 | 函数功能 |
---|---|---|
Concat | concat(s1,s2....sn) concat(‘hello’,‘AAA’)返回 helloAAA | 把传入的参数连接成一个字符串。 如果有值为null,则最终返回null。 忽略null值则使用concat_ws函数。 |
Length | length('hello world')结果为11 length('加油中国')结果返回为12 | 返回任何数据类型的字节数 |
Char_length | Char_length('中国') 返回为2 | 返回字符个数 |
Upper | upper('abcd')返回为ABCD | 将字符串转为大写 |
Ltrim | Ltrim(‘ abc’)返回为’abc’ | 去除字符串左边的空格 |
Rtrim | Rtrim(‘abc ’)返回为’abc’ | 去除字符串右边的空格 |
Replace | Replace('abcccd','c','x') 返回为’abxxxd’ | 将abcccd中c替换为x |
Locate | Locate('a','helloaaa') 返回 6 | 返回子串 a 在字符串 helloaaa 第一个出现的位置,不存在则返回 0 |
Substring | substring('Johnson',5,3) 返回为‘son’ | 从第5个位置开始截取长度为3的字符串 |
案例:
-- CONCAT把传入的参数连接成一个字符串 select CONCAT('hello','world') as word select CONCAT(name,':',tel) 联系方式 from student -- length select name,LENGTH(name) from student -- replace update student set name = REPLACE(name,'林','Lin'); -- locate select LOCATE('a','peace and love') -- Substring select SUBSTR('hello world' ,2,3)
函数名 | 示例 | 函数功能 |
---|---|---|
Now | now()返回系统当前时间 | 返回系统当前时间 |
TIMESTAMPDIFF | 语法: TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) 例: SELECT TIMESTAMPDIFF (MONTH,'2009-09-01','2009-10-01'); 返回 1 | 返回日期或日期时间表达式之间的整数差 unit可以是: MICROSECOND (microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR. |
DateAdd | DATE_ADD('1998-01-02', interval 1 YEAR) 返回 1999-01-02 | 向日期指定部分添加数字,其中: YEAR表示是年, month表示月, day表是日 Interval--时间间隔 |
Dayofweek | dayofweek('2008-08-08‘)返回 6 dayofweek:(1 = Sunday, 2 = Monday, ..., 7 = Saturday) | 返回一周中的位置 |
YEARWEEK(date[,mode]) | select yearweek('2008-8-8'); 返回200831 mode:0-7 | 获取年份和周数 |
DateDiff | select datediff('2008-08-08', '2008-08-01'); 结果返回为 7 | 两个日期相减 date1 - date2,返回天数 |
Date | date('2008-09-10 07:15:30'); 返回 2008-09-10 | 以字符串形式返回某个日期部分。 |
案例:
select date('2008-09-10 07:15:30'); -- 日期 2008-09-10* select time('2008-09-10 07:15:30'); -- 07:15:30.123456* select year('2008-09-10 07:15:30'); -- 年 2008* select quarter('2008-09-10 07:15:30'); -- 季度 3* select month('2008-09-10 07:15:30'); -- 月 9* select week('2008-09-10 07:15:30'); -- 一年中的第几周 36* select day('2008-09-10 07:15:30'); -- 日 10 select hour('2008-09-10 07:15:30'); -- 小时 7 select minute('2008-09-10 07:15:30'); -- 分钟 15 select second('2008-09-10 07:15:30'); -- 秒 30 -- 当前时间 select now() -- 返回两个日期之间的时间 生日 和当前时间 做对比,得出年龄 update student set age=TIMESTAMPDIFF(year,birthDay,NOW()) -- date_Add 向指定日期添加 一段时间 year是年 month 是月 day是日 INTERVAL 表示时间差 select DATE_ADD('1999-08-02',INTERVAL 10 MONTH) -- dayofweek 返回一周中的位置 select DAYOFWEEK(NOW()) -- dateDiff 两个日期相减,返回天数 select DATEDIFF(NOW(),birthday) from student
函数名 | 示例 | 函数功能 |
---|---|---|
Abs | Abs(-1)返回为”1” | 求绝对值 |
Ceiling | Ceiling(24.1)结果返回25 | 大于24.1的最小整数 |
Floor | Floor(24.1)结果返回为24 | 小于24.1的最大整数 |
Power | Power(2,3)结果返回为“8” | 计算2的3次方 |
Round | Round(68.32,1)结果返回为68.30 | 返回一个数字,舍入到指定的长度或精度 |
Sign | Sign(123)结果返回为1 | 返回数值的符号,正负零分别返回1, -1, 0 |
Sqrt | Sqrt(16)结果返回为“4” | 开平方 |
PI | PI() 返回3.141593 | 圆周率 |
Rand([x]) | Rand()/Rand(x) | 返回一个随机浮点值 |
-- 绝对值 select ABS(-4) -- 返回符号 select SIGN(-6) -- 产生随机数 select RAND()
函数名 | 示例 | 函数功能 |
---|---|---|
Convert | convert(1234,char(4)) 结果返回为”1234” | 数据类型转换函数,将1234数字类型转换为char类型 |
VERSION | Version() | 返回数据库的版本号 |
LAST_INSERT_ID | LAST_INSERT_ID() | 返回最后生成的AUTO_INCREMENT值 |
ifnull(expr,value) | select ifnull(city,'未知') from studentInfo | 如果表达式的值非空,则返回表达式的值,否则返回value |
PASSWORD/MD5 | PASSWORD(str)/MD5(str) | 对数据加密 |
select user,host from mysql.user 返回计算机的名字 | 返回当前用户登录的计算机名字 | |
SELECT Current_User 返回当前用户的登录名 | 返回当前用户的名字 |
-- 查看版本号 select VERSION() -- 查看当前用户登录的计算机名字 select user,host from mysql.user
数据单列或多列查询
使用order by对查询结果排序
使用where子句对查询结果进行筛选
使用limit 返回限定的行数
内置函数:字符串函数、日期函数、数学函数、系统函数
学生信息表(StudentInfo表)
成绩表(Exam表)
模糊查询提取的数据不一定是确切的。
它允许用户输入的查询条件也是模糊的、大概的、不特别明确的。
例如,只查询王姓学员的信息
LIKE运算符
regexp 使用正则模式:
通配符 | 说明 |
---|---|
% | 代表任意长度的字符串 |
_ | 下划线。代表一个字符 |
escape | 转义字符 |
-- 查询数据库表中姓孙的学生 SELECT * FROM studentinfo WHERE sname LIKE '孙%'; -- 查询包含字符"张"的学生信息,需要中间匹配 SELECT * FROM studentinfo WHERE sname LIKE '%张%'; -- 查询以字符"乔"结尾的学生信息,需要结尾匹配 SELECT * FROM studentinfo WHERE sname LIKE '%乔';
-- 查询"黄_"的学生 SELECT * FROM studentinfo WHERE sname LIKE '黄_'; -- 查询所有Email的第二个字符为“u”的学生信息 SELECT * FROM StudentInfo WHERE Email LIKE '_U%';
转义字符 escape
ESCAPE ‘/’含义:/之后的_不作为通配符,只作为普通的字符串
-- 查询“李_"的学生 ( 比较特殊的名字叫李_ ) select * from student where sname like '李/_' ESCAPE '/';
正则模式REGEXP操作符
符号 | 含义 |
---|---|
. | 匹配任意单个的字符。 |
[ ] | 匹配在[]内的任意一个字符 |
[^] | 匹配不在[]内的任意一个字符 |
* | 匹配零个或多个在它前面的字符 |
^ | 匹配文本的开始字符 |
$ | 匹配文本的结尾字符 |
+ | 匹配+前面的字符1次或多次 |
{n} | 匹配前面的字符至少n次 |
示例:
-- 查询出所有的身份证号以14开头,第三位必须为0或6 的学生信息 select * from studentinfo where idcard REGEXP '^14[0|6]' -- 查询学生电话号 是 13开头的人的信息 SELECT * FROM studentinfo WHERE phone regexp '^[1][3]';
常见的匹配条件:
查询条件 | 匹配结果 | 描述 |
---|---|---|
REGEXP '^4' | 4% | 以4开头的 |
REGEXP '4$' | %4 | 以4结尾的 |
REGEXP '[0-2]' | 0 1 2 | 从0到2 |
REGEXP 'b{2}$' | %bb | 以两个b结尾 |
REGEXP 'b{2}' | bb,bbbb,bbbbbbb | 包含两个b |
根据某个字段值的区间范围来查询符合条件的记录,这个范围内有多少数据并不明确
示例:
-- 在student表中查询出年龄在18~20之间的学生信息 SELECT * FROM studentinfo WHERE Age BETWEEN 18 AND 20;
用来匹配某个字段的值是几个可数的选项值之一
示例:
-- 查询出学生家在安徽或者浙江的学生信息 SELECT * FROM StudentInfo WHERE Province IN('安徽','浙江') ;
获取某些列的最大值、最小值、平均值等统计分析信息,有时候还需要计算出究竟查询到多少行数据项。
SUM函数
SUM函数用于对数据求和,返回选取结果集中某列所有值的总和,可以计算单列或多列的总和。
聚合函数,与普通列一起进行查询:
-- 示例:查询出Exam表中学号(stuid)为2023002的所有科目的总成绩 select sum(exam) as 总成绩 ,stuid 学号 from exam where stuid=2023002
MAX/MIN 最大值和最小值函数。
# 分别查询Exam表中科目编号(SubjectId)为1的最高成绩和最低成绩 SELECT MAX(Exam) AS '最高成绩', MIN(Exam) AS '最低成绩' FROM Exam WHERE SubjectId=1 ;
AVG 求平均值函数
# 要求查询出所有及格学员的平均分 SELECT AVG(Exam) FROM Exam WHERE Exam>=60 ;
COUNT 求总数函数
COUNT函数返回符合条件的查询结果中非空值的计数
# 查询出在校学生的总人数 SELECT COUNT(*) AS 学生人数 FROM StudentInfo;
使用Group By进行数据分组查询。
成绩表(Exam)中记录了三门课各个学生的成绩,课程编号(SubjectId)分别是1、2、3。
要统计不同课程的平均分。首先要把相同的SubjectId都分为一组,这样就数据就分成了三组,然后针对每一组使用聚合函数AVG取平均值
示例:
-- 查询每个科目的平均分 SELECT SubjectId,AVG(Exam) as 平均分 FROM EXAM GROUP BY SubjectId;
查询出每个班级的学生人数
SELECT ClassID AS '班级编号', COUNT(*) AS '班级人数' FROM StudentInfo GROUP BY ClassID;
每个省份中学生的最小年龄,并结果按照升序排列
SELECT province AS '所在省份',MIN(Age) AS '最小年龄' FROM StudentInfo GROUP BY province ORDER BY MIN(Age) ASC ; # DESC 降序
统计每个班级的男女生人数
SELECT ClassId as '班级编号',Gender as '性别', COUNT(StuId) as '人数' FROM StudentInfo GROUP BY ClassID,Gender ;
Having子句-分组查询的条件筛选
查询出所在省份超过2个学生的最小年龄
SELECT province AS '所在省份',MIN(Age) AS '最小年龄' FROM StudentInfo GROUP BY province HAVING COUNT(StuID)>2 ORDER BY MIN(Age) ASC ;
在查询语句中WHERE、GROUP BY、HAVING可以一起使用,其使用使用顺序如图
查询每个课程中考试及格总人数和及格平均分,并显示及格平均分在80分以上的课程记录
SELECT SubjectId,AVG(Exam) as 平均分,COUNT(*) AS '及格人数' FROM EXAM WHERE EXAM>=60 GROUP BY SubjectId HAVING AVG(Exam)>80;
在实际开发过程中很多时候需要同时使用多个表中的数据。
多表连接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征。
常用的连接有:内连接、外连接、交叉连接(笛卡尔乘积连接)。
内连接
内连接和外连接一样都是最常用的连接查询,它根据表中共同的的列进行匹配,特别是两个表存在主外键关系时,通常会使用到内连接查询。
外连接
外连接是至少返回一个表中的所有记录,根据匹配条件有选择性地返回另一张表的记录。外连接的体现形式为两种:左外链接、右外连接。
交叉连接(笛卡尔乘积)
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行再一一组合,相当于两个表“相乘”。这种情况在数据库中,叫做笛卡尔乘积。
select A.*,B.* from student A,classinfo B
执行该语句发现并没有报错,但是查询所得到的结果并不是所需要的。
这是因为在查询过程中没有使用任何的匹配条件,就会将A表中的数据每取出一行就和B表中的数据进行组合。
这种情况在数据库中叫做:笛卡尔乘积,也就是交叉连接。
笛卡尔乘积返回的结果是存在大量冗余的,多数情况下,查出来的很多内容都是无用的,所以尽量不要使用!
1)Where子句多表查询
使用where子句实现多表连接查询(隐性连接)。
select s.sname 姓名,s.age 年龄,s.sex 性别,s.addr 籍贯,c.className 班级 from student s,classinfo c where s.classid = c.classid
2)Join...On
使用join. ..on实现多表连接查询(显性连接) 1、内连接(等值连接)
inner. . . join:返回的结果集是两个表中所有想匹配的数据,抛弃掉不匹配的数据。
# 语法 select ... from表1 [inner] join 表2 on条件表达式 # 案例: select s.sname,s.age,c.classname from student s JOIN classinfo c on s.classid=c.classid
2、自连接
自连接是指表与其自身连接查询信息。在有些情况下,需要表自身连接来查询信息。
比如:在员工表emp中查询员工信息以及对应的领导名称。
select a.ename 员工姓名,a.job 员工职位,b.ename 所属领导 from employee a JOIN employee b on a.mgr=b.empno
在外连接中两个表有主从之分。
外连接是以A表为主表,B表为副表, 查出A表中的所有信息,以及在B表中对应的相关信息,如果B表中没有相关信息,则返回null。
外连接可以分为2种:左外链接、右外连接。
外连接的语法只需要把内连接的关键字INNER改为OUTER 即可,同时OUTER可以省略
1)左外链接
-- 查询所有班级对应的学生 select c.classname, s.sname from classinfo c left JOIN student s on c.classid=s.classid -- > 显示结果中,有些班级没有学生。所以就是null表示 # 如果使用内连接: select c.classname,s.sname from classinfo c,student s where c.classid=s.classid -- >内连接只显示能够匹配到的值,没有学生的班级不会显示。
2)右外连接
右外联接是左外联接的反向联接,将返回右表的所有行,如果右表的某行在左表中没有匹配行,则将左表返回空值
返回包括右表中的所有记录和左表中关联字段相等的记录。
select c.classname, s.sname from classinfo c right JOIN student s on c.classid=s.classid # 返回右表中在左表没有匹配到内容的,返回null,比如没有班级的学生
UNION用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。
UNION内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。 每条 SELECT 语句中的列的顺序必须相同.
允许重复的值,请使用 UNION ALL
示例:
select sname from student union select classname from classinfo;
Union和Join子句不同,因为union 总是垂直组合结果集,而join水平附加输出。
我们可以通过以下图例来理解它:
子查询是一个嵌套在SELECT、INSERT、UPDATE 或 DELETE语句中的查询。
嵌套在其它查询中的查询称之为子查询或内部查询。
包含子查询的查询称之为主查询或外部查询
分为三类:
通过IN、ANY、ALL修改的比较运算符引入的列表上操作的子查询
通过比较运算符引入且必须返回单个值的子查询
通过EXISTS引入的存在测试的子查询
案例:
-- 查询和张三年龄相同的人的信息 select * from student where age=(select age from student where sname='张三')
数据库引擎将子查询作为虚表执行查询操作。
子查询可作为联接语句中的一个表,也可作为选择语句中的一个值。
子查询的执行依赖于嵌套查询。顺序从最内层开始,一层一层向外执行,
外层的嵌套查询可以访问内层嵌套查询的结果, 相比变量方式执行效率更高,
子查询还可以将多表的数据组合在一起。
问题:查询张三的同班同学名单
用子查询实现 :
编写复杂的子查询(尤其是多层嵌套的子查询),最简单的方法是分解查询。
从最内层的子查询开始分解,将嵌套的SQL语句拆分为独立的SQL语句分别执行;
当确认结果无误后,再重新组合在一个语句中。
-- 同班同学 select s.sname,c.className from student s join classinfo c on s.classid=c.classId where s.classId = (select classid from student where sname='张三')
1)使用IN、NOT IN的子查询。
IN后面的子查询允许返回多行记录,用于从一个范围来限制主查询的条件
-- 查询存在学生年龄大于20的班级 select * from classinfo where classId in (select classid from student where age >20) -- 查询不存在学生年龄大于20的班级 select * from classinfo where classId not in (select class_id from student where age >20)
2)使用ALL的子查询
通过比较运算符将一个表达式的值或列值与子查询返回的一列值中的每一行进行比较,只要有一次比较 的结果为FALSE,则ALL测试返回FALSE。
-- 查询 成绩比1002班所有成绩 都好的学生信息 select * from student where score > ALL(select score from student where class_id = (select classId from classinfo where className='1002班'))
3)使用any/some
按照比较运算符、表达式或字段对子查询的结果每一行进行一次计算和比较。
只要有一次满足条件,那 么 ANY 的结果就是真;
当子查询每行结果与ANY前面的表达式或字段比较结果全为假时,则结果为假.
-- 查询 成绩只要比1002班中某位学生成绩好的 学生信息 select * from student where score > ANY(select score from student where class_id = (select classId from classinfo where className='1002班')) ORDER BY score desc
4)使用EXISTS的子查询
使用EXISTS的子查询 :EXISTS代表存在量词“彐” 。
带有EXISTS谓词的子查询不返回任何实际数据 只产生逻 辑真值“true”或逻辑假值“false”。
-- 查询学生信息,条件是学生班级不是1002班中的 select * from student s where s.class_id not in (select classId from classinfo where className='1002班') # 或者 select * from student s where not EXISTS (select c.classId from classinfo c where s.class_id=c.classId and className='1002班')
👆最后一个属于相关子查询。
不相关子查询: 内部查询的执行独立于外部查询,内部查询仅执行一次,执行完毕后将结果作为外部查询的条件使用
相关子查询: 内部查询的执行依赖于外部查询的数据,外部查询每执行一次,内部查询也会执行一次。每一次都是外部查询先执行,取出外部查询表中的一个元组,将当前元组中的数据传递给内部查询,然后执行内部查询。根据内部查询执行的结果,判断当前元组是否满足外部查询中的where条件,若满足则当前元组是符合要求的记录,否则不符合要求。然后,外部查询继续取出下一个元组数据,执行上述的操作,直到全部元组均被处理完毕。