* sql 语句不区分大小写
* 一条sql 语句结束之后要用英文分号隔开;
* sql关键字之间以空格进行分隔
* sql之间可以不限制换行(可以用空格的地方就可以有换行)
SQL分类根据SQL指令完成的数据库操作的不同,可以将SQL指令分为四类:
* DDL Data Definition Language 数据定义语言
1. 用于完成对数据库对象(数据库、数据表、视图、索引等)的创建、删除、修改
* DML Data Manipulation Language 数据操作/操纵语言
1. 用于完成对数据表中的数据的增加、删除、修改操作
2. 添加:将数据存储到数据表
3. 删除:将数据从数据表移除
4. 修改:对数据表中的数据进行修改
* DQL Data Query Language 数据查询语言
1. 用于将数据表中的数据查询出来
* DCL Data Control Language 数据控制语言
1. 用于完成事物管理等控制性操作
数据库 --->表---> 字段
mysql 基本命令:
创建数据库:
create database db_test;
不知道要创建的数据库存不存在可以使用:
create database if not exists db_test;
在创建数据库的同时指定数据库的字符集(字符集:数据存储在数据库中采用的编码格式)
create database db_test character set utf8;
修改数据库的字符集 :
alter database db_test character set utf8;
查看数据库:show databases;
显示指定名称的数据的创建的sql 指令:
show create database db_test;
使用数据库、查看数据库里所有表格,查看表格内容
use db2019;
show tables;
select * from payment;
查询表:
select * from table;
修改数据库:修改数据库的字符集 :
alter database db_test character set utf8;
删除数据库 (输出数据库时会删除当前数据库中所有的数据表以及数据表中的数据)
drop database db_test;
如果数据库不存在,可以添加条件去删除数据库,如果存在就删除
drop database if exists tb_test;
使用和切换数据库:
use db_test;
DDL数据表的操作:
创建数据表:
其中students 表示的是学生表,not null 表示字段非空 ,unique表示字段唯一 ,char 表示字段的类型是定长,varchar 表示的是字段类型可变
create table sudents(
stu_num char(8) not null unique,
stu_name varchar(20) not null,
stu_gender char(2) not null,
stu_age int not null ,
stu_tel char(11) not null unique,
stu_qq varchar(11) unique
);
查询数据库里所有的数据表:show tables;
查询表结构:desc students;
删除数据表:drop table students;
删除数据表不存在时:drop table if exists students;
修改数据表:#修改表名(将students 表名修改成stus)
alter table students rename to stus;
数据表也是有字符集的,默认和数据库的字符集一致
alter table <tableName> character set utf8;
添加字段(列)
alter table <tableName> add <columnName> varchar(200);
修改字段的列表和类型
alter table <tableName> change <oldColumnName> <newCloumnName> <type>;
只修改字段类型alter table <tableName> modify <columnName> <newType>;
删除字段(列)alter table <tableName>drop <columnName>;
MySQL数据类型:数据类型,指的是数据表中的列中支持存放的数据的类型1、 数值类型:
在mysql中有多种数据类型可以存放数值,不同的类型类型内存空间大小范围说明tinyint 1byte 有符号:-128~127无符号(unsigned):0-255
smallint 2byte(16bit)有符号:-32768~32767 无符号:0-65535
mediumint 3byte 有符号:-231~231-1无符号:0-2^32-1
int/integer(常用) 4byte 整数
bigint 8byte大型整数
float 4byte 单精度
double 8byte 双精度
decimal 第一个参数+2decimal(10,2)表示数值一共有10位,小数位有2位
2、字符类型:存储字符序列的类型类型字符长度说明
char 0-255字节定长字符串,最多可以存储255个字符,当我们指定数据表字段为char(n),此列中的数据量长为 n个字符,如果添加的数据少于n,则补"\u0000"至n长度
varchar 0-65536字节可变长度字符串,此类型的类最大长度为65536
tinyblob 0-255字节存储二进制字符串
blob 0-65535 存储二进制字符串
mediumblob 0-1677215存储二进制字符串
longblob 0-4294967295(4GB)存储二进制字符串
tinytext 0-255文本数据(字符串)
text 0-65535文本数据(字符串)
mediumtext文本数据(字符串)
longtext文本数据(字符串)
3、日期类型:在mysql 数据库中,我们可以使用字符串来存储时间,但是如果我们需要基于时间字段进行查询操作(查询操作在某个时间段内的数据)就不便于查询实现类型格式说明
date 2022-05-05日期,只存储年月日
time 19:21:50时间,只存储时分秒
year 2022年份
datetime 2022-05-05 19:21:50 日期+时间,存储年月日时分秒
timestamp时间戳字段约束在创建数据表的时候,指定的对数据表的列的数据
限制性的要求(对表的列中的数据进行限制)为什么要给表中的列添加约束?
* 保证数据的有效性
* 保证数据的完整性
* 保证数据的正确性
字段常见的约束有哪些?
* 非空约束(not null ) :限制此列的值必须提供,不能为null
* 唯一约束(unique):在表中的多条数据,此列的值不能重复 (如果字段设置唯一约束没有设置非空约束,其他字段不做干扰的话,该字段可以存在多个空(null))
* 主键约束 (primary key ):非空+唯一 ,能够唯一标识数据表中的一条数据
* 外键约束(foreign key): 建立不同表之间的关联关系
主键约束:(主键不能为空的)主键--就是数据表中记录的唯一标识,在一张表中只能有一个主键(主键可以是一个列,也可以是多个列的组合)当一个字段声明为主键后,添加数据时:
* 此字段数据不能为null
* 此字段数据不能重复
创建表时定义主键
create table students(
sid char(4) primary key,
sname varchar(4) not null,
sex char(2) );
或者
create table students(
sid char(4),
sname varchar(4) not null,
sex char(2),
primary key(sid));
删除数据表主键约束:
alter table <tableName> drop primary key;
添加主键约束:(还可以修改类型char(4)改成int)
alter table <tableName> modify students char(4) primary key;
主键的自动增长:在我们创建一张数据表时,如果数据表中有可以作为主键(例如:学生表的学号,图书表的ISBN)我们可以直接设这个列为主键;
当有些数据表中没有合适的列作为主键时,我们可以额外定义一个 与记录本身无关的列(ID)作为主键,此列数据无具体的含义主要用于标识一条记录,
在mysql中我们可以将此列定义为int,同时设置为自动增长,当我们想数据表中新增一条记录时,无需提供ID列的值,它会自动生成。定义主键自动增长
只需记录type_name ,type_remark
create table types{
type_id int primary key auto_increment,
type_name varchar(20) not null,
type_remark varchar(100)
};
注意:自动增长从1开始,每增加一条记录,自动的增长的列会自动+1,当我们把某条记录删除之后再添加数据,自动增长的数据也不会重复生成
(自动增长只保证唯一性,不保证连续性)联合主键: students
stu_num stu_name stu_gender stu_age
101 张三 男 21
102 李四 女 20
cources
course_id course_name course_xf(sorce)
1 java 4
2 python 3
grades
stu_num course_id score
101 1 59
101 2 60
102 1 78
102 2 59
定义联合主键只能用这种方式创建联合组件。
create table gredes(
stu_num char(8),
course_id int,
score int,
primary key(stu_num,course_id));
注意:在实际企业项目的数据库设计中,联合主键使用频率并不高;当一张数据表中没有明确的字段可以作为主键时,我们可以额外添加一个ID字段作为主键。DML数据操纵语言完成对数据表中数据的插入、删除、修改操作CREATE TABLE students
(
stu_num
char(8) NOT NULL,
stu_name
varchar(20) NOT NULL,
stu_gender
char(2) NOT NULL,
stu_age
int NOT NULL,
stu_tel
char(11) NOT NULL,
stu_qq
varchar(11) DEFAULT NULL,
PRIMARY KEY (stu_num
),
UNIQUE KEY stu_tel
(stu_tel
),
UNIQUE KEY stu_qq
(stu_qq
)) ENGINE=InnoDB DEFAULT
CHARSET=utf8;
1、插入数据语法:
insert into <tableName> (columnName,columnName....) values (value1,value2.....)
示例:
向数据表中指定的列添加数据(不允许为空的列必须提供数据)insert into students(stu_num,stu_name,stu_gender,stu_age,stu_tel) values ('175001',"sss","男",21,'123456');
数据表名后括号里的字段名列表顺序可以不与表中一致,但是values中值的顺序必须与表名后括号里字段名顺序对应
当要向表中的所有列添加数据时,数据表名后面的字段列表可以省略,但是values中的值的顺序要与数据表定义的字段(表创建时)保持一致;
不过在项目开发中,及时要向所有列添加数据,也建议将列名的列表显式写出来(增强SQL的稳定性)
2、删除数据从数据表中删除满足特定条件(所有) 的数据语法:
删除所有delete from <tableName>;
按条件删除delete from <tableName> where conditions ; (可以是指定某个值,也可以是指定一个区间)
3、修改数据对数据表中已经添加的记录进行修改语法
update <tableName> set columnName=value,columnName2=value2 [where conditions]特殊示例,如果update 语句没有where 子句,则表示修改当前表中所有行(记录)update stus set stu_name ='Tom';
DQL数据查询语言从数据表中提取满足特定条件的记录
* 单标查询
* 多表联合查询
查询基础语法
select 关键字后指定要显示查询到的记录的哪些列
select colnumName1 [colnumName2,colnumName3....] from <tableName> //至少要有一列,为空就报错##如果要显示所有的列,则可以用*代替字段名(在项目开发中不建议使用)
select * from <tableName>;
where子句:在删除、修改及查询的语句后都可以添加where子句(条件),用于筛选满足特定的添加的数据进行删除、修改和查询操作。
delete from tableName where conditionsupdate tableName set ..columnName=value... where conditionsselect .... from tableName where conditions;
条件
等于
select * from stus where stu_num = '111';
!= <> 不等于
select * from stus where stu_num != '111';
select * from stus where stu_num <> '111';
> 大于
select * from stus where stu_age>18;
< 小于
select * from stus where stu_age <18;
>= 大于等于
select * from stus where stu_age >=20;
<= 小于等于select * from stus where stu_age <=20;
between and 区间查询
between v1 and v2 [v1,v2]select * from stus where stu_age between 18 and 20;
条件逻辑运算:在where 子句中,可以将多个条件通过逻辑预算(and or not )进行连接,通过多个条件来筛选要操作的数据。
and 并且
筛选多个天剑同时满足的记录select * from stus where stus_gender='女' and stu_age<21;## or 或者 筛选多个条件中至少满足一个条件的记录select * from stus where stus_gender='女' or stu_age<21;
not 取反
select * from stus where stu_age not between 18 and 20;
LIKE子句在where 子句的条件中,我们可以使用like关键字来实现模糊查询语法select * from tableName where columnName like 'reg';
在like 关键字后的reg 表达式中%表示任意多个字符[%o%包含字母o]_表示任意一个字符[_o% 第二个字母为o]对查询结果的处理设置查询的列声明显示查询结果的指定列
select colnumName1,colnumName2,....from stus where stu_age>20;
计算列对从数据表中查询的记录的列进行一定的运算之后显示出来## 出生年份 = 当前年份 - 年龄
select stu_name ,2021-stu_age from stus;
as 字段别名我们可以为查询结果的列名 取一个语义性更强的别名 (如下案列中as关键字也可以省略)
select stu_name as 姓名, 2021-stu_age as 出生年份 from stus;
distinct 消除重复行从查询的结果中将重复的记录消除
distinct select distinct stu_age from stus;
order by 排序将查询到的满足条件的记录按照指定的列的值升序/降序排序语法
select * from tableName where conditions order by columnName asc |desc;
* order by columnName 表示将查询结果按照指定的列排序
* asc 按照指定的列升序(默认)
* desc 按照指定的列降序
单字段排序
select * from stus where stu_age>15 order by stu_gender desc;
多字段排序:先满足第一个排序规则,当第一个排序的列的值相同时再按照第二个列的规则排序
select * from stus where stu_age>15 order by stu_gender asc,stu_age desc;
聚合函数sql 中提供了一些可以对查询的记录的列进行计算的函数--聚合函数
* count()统计函数,统计满足条件的指定字段值的个数(记录数)
* max() 计算最大值,查询满足条件的记录中指定列的最大值
* min() 计算最小值,查询满足条件的记录中指定列的最小值
* sum() 计算和,查询满足条件的记录中,指定的列的值和总和
* avg() 求平均值,查询满足条件的记录中计算指定列的平均值
日期函数和字符串函数日期函数当我们向日期类型的列添加数据时,可以通过字符串类型赋值(字符串的格式必须为yyyy-MM-dd hh:mm:ss)如果我们想要获取当前系统时间添加到日期类型的列,可以使用now() 或者 sysdate()
通过字符串类型,给日期类型的列赋值 (insert into 手动赋值 )
通过now() 获取当前时间 (insert into .... values (......,now(),.....))
通过sysdate()获取当前时间 (insert into sysdate())
可以在mysql 中直接用now(); sysdate()查询当前的时间。
例: select now(); 或者 select sysdate();
字符串函数就是通过sql指令对字符串进行处理示例:
concat (column1,column2,column3...) 拼接多列select concat (stu_name,'-',stu_gender) from stus;#upper(column) 将字段的值转换为大写select upper(stu_name) from stus;#lower(column) 将字段的值转换为小写#substring(column,start ,len) 从指定列中截取部分显示start从1开始分组查询 -- group by分组--就是将数据表中的记录按照指定的类进行分组语法select 分组字段/聚合函数 from 表名 [where 条件] group by 分组列名 [having 条件]
注意:如果没有group by 就不能使用 having [order by 排序字段]
* select 后使用* 显示对查询的结果进行分组之后,显示每组的第一条记录(这种显示通常是无意义的)
* select 后通常显示分组字段和聚合函数(对分组后的数据进行统计、求和、平均值等)
* 语句的执行顺序:1、先根据where条件从数据库查询记录,2、group by 对查询的数据记录进行分组3、执行having对分组后的数据进行筛选
示例:#先对查询的学生信息按性别进行分组(分成了男、女两组),然后再分别统计每组学生的个数
select stu_gender ,count(stu_num) from stus group by stu_gender;
先对查询的学生信息按性别进行分组(分成了男、女两组),然后再计算每组的平均年龄
select stu_gender,avg(stu_age) from stus group by stu_gender;
先对学生按年龄进行分组(分了16,17,18等几组),然后统计各组的学生数量,还可以对最终的结果排序
select stu_age ,count(stu_num) from stus group by stu_age order by stu_age;
查询性别为‘男’的学生,按年龄进行分组,然后分别统计每组的人数,再筛选当前组人数>1的组,在按年龄的升序显示出来
select stu_age ,count(stu_num) from stus where stu_gender='男'group by stu_age having count(stu_num)>1 order by stu_age;
分页查询-- limit当数据表中的记录比较多的时候,如果一次性全部查询出来显示给用户,用户的可读性,体验性就不太好,因此我们可以将这些数据分页进行展示。
语法:select ...from ..[where ...]limit param1,param2
* param1 int,表示获取查询语句的结果中的第一条数据的索引(索引从0开始)
* param2 int ,表示获取的查询记录的条数(如果剩下的数据条数<param2,则返回剩下的所有记录)
案例对数据表中的学生信息进行分页显示,总共有10条数据,我们每页显示3条
总记录数 count 10
每页显示 pageSize 3
总页数: pageCount= count%PageSize ==0 ? count/pageSize :count/pageSize+1
查询第一页select * from stus [where ... ] limit 0,3;
查询第二页select * from stus [where ... ] limit 3,3;.......
如果在一张数据表中
pageNum 表示查询的页码
pageSize 表示每页显示的条数#通过分页语句如下:
select * from <tableName> [where...] limit (pageNum-1)*pageSize,pageSize;
数据表的关联关系关联关系mysql 是一个关系型数据库,不仅可以存储数据,还可以维护数据与数据之间的关系- -- 通过在数据表中添加字段建立外键约束数据与数据之间的关联关系 分为四种:
* 一对一关联
* 一对多关联
* 多对一关联
* 多对多关联
一对一关联 人 - 身份证
一个人只有一个身份证,一个身份证只对应一个人 学生-年级
一个学生只有一个学籍,一个学籍也对应唯一的一个学生 用户-用户详情 一个用户只有一个详情,一个详情页只对应一个用户数据关联方案:
方案1: 主键关联 -- 两张数据表中主键相同的数据为相互对应的数据
方案2: 唯一外键 -- 在两个表的任意一张表中添加一个字段添加外键约束与另一张表主键关联,并且将外键列添加唯一约束(该表的外键和另一个表的主键一一对应);
一对多与多对一班级
-- 学生 (一对多) 一个班级包含多个学生学生
-- 班级 (多对一) 多个学生可以属于同一个班级数据关联方案:在多的一方添加外键,与一的一端主键进行关联多对多关联学生 -- 课程 一个学生可以选择多门课,一门课程可以给多个学生选择数据关联方案:额外创建一张关系表来维护多对多关联--在关系表中定义两个外键,分别与两个数据表的主键进行关联。关系表除了定义两个表的外键之外,还可以新增其他的字段,如果是在学生和课程两表之间绑定多对多的关系,在关系表中除了两表的外键字段外还可以添加分数,没条数据的更新时间。外键约束外键约束 --- 将一个列添加外键约束与另一张表的主键(唯一列)进行关联之后,这个外键约束的列添加的数据必须要在关联的主键字段中存在案例: 学生表 与 班级表
1、先创建班级表
create table classes(class_id int primary key auto_increment,class_name varchar(40) not null unique,class_remark varchar(200));
2、创建学生表(在学生表中添加外键与班级表的主键进行关联)
【方式一】 在创建表的时候,定义cid字段,并添加外键约束
由于 cid 列,要与classes 表的class_id进行关联,因此cid 字段类型和长度要与class_id一致create table students(
stu_num char(8) primary key,
stu_name varchar(20) not null,
stu_gender char(2) not null,
stu_age int not null,
cid int,
constraint FK_STUDENTS_CLASSES foreign key(cid) references classes(class_id));
【方式二】 先创建表,再添加外键约束
create table students(
stu_num char(8) primary key,
stu_name varchar(20) not null,
stu_gender char(2) not null,
stu_age int not null,
cid int
);
在创建表之后,为cid 添加外键约束
alter table students add constraint FK_STUDENTS_CLASSES foreign key(cid) references classes(class_id)
删除外键约束alter table students drop foreign key FK_STUDENTS_CLASSES;
3.向班级表添加班级信息insert into classes(class_name,class_remark) values('java2020','...');insert into classes(class_name,class_remark) values('java2021','...');insert into classes(class_name,class_remark) values('java2022','...');insert into classes(class_name,class_remark) values('java2023','...');select * from classes;
4、向学生表中添加学生信息insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('2022001','李四','男',19,1);
添加学生时,设置给cid 外键列的值必须在其关联的主表classes的class_id列存在insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('2022001','李四','男',19,6);
报错:> 1452 - Cannot add or update a child row: a foreign key constraint fails (test
.students
, CONSTRAINT FK_STUDENTS_CLASSES
FOREIGN KEY (cid
) REFERENCES classes
(class_id
))
当学生表中存在学生信息关联班级表的某条记录时,就不能对班级表的这条记录进行修改ID和删除操作students表
说明: 其中stu_num 是主键
cid是关联班级class_id 的外键
stu_num stu_name stu_gender stu_age cid
2022001 李四 男 19 1
2022002 张三 男 18 2
2022003 王五 女 17 3
2022004 mike 男 17 4
2022005 小z 女 20 1
2022006 小y 女 21 1
classes 表:
说明:class_id是主键
class_id class_name class_remark
1 java2020 ...
2 java2021 ...
3 java2022 ...
4 java2023 ...
关键操作
--级联如果现在需要对classes 表中的class_name = java2020 中的class_id 进行修改,改成5的实现步骤;
* 将引用java2020班级id 的学生记录中的cid 改成NULL
* 在修改班级信息表中java2020记录的class_id
* 将学生表中cid 设置为NULL的记录的cid重新修改成java2020这个班级的新的id
如果是直接修改class_id 会出现的报错:执行:
update classes set class_id =5 where class_name='java2020';
报错:> 1451 - Cannot delete or update a parent row: a foreign key constraint fails (test
.students
, CONSTRAINT FK_STUDENTS_CLASSES
FOREIGN KEY (cid
) REFERENCES classes
(class_id
))
现在按照上面的三个步骤:
1、将学生中的cid 改成NULL执行:update students set cid=NULL where cid=1;
运行结果:
2022001 李四 男 19
2022002 张三 男 18
22022003 王五 女 17 3
2022004 mike 男 17 4
2022005 小z 女 20
2022006 小y 女 21
2、修改班级信息表中的java2020的class_id为5执行:
update classes set class_id =5 where class_name='java2020';
运行结果:
2 java2021 ...
3 java2022 ...
4 java2023 ...
5 java2020 ...
3、将学生表中cid 为NULL的全部改成5执行:
update students set cid=5 where cid is NULL;
运行结果:
2022001 李四 男 19 5
2022002 张三 男 18
22022003 王五 女 17 3
2022004 mike 男 17 4
2022005 小z 女 20 5
2022006 小y 女 21 5
上面用用到的方法就常规的方法,相对而言比较繁琐,我们还可以直接用级联的方式对关联的班级表去进行删除和修改。
使用级联操作来实现:
1、在添加外键时,设置级联修改 和级联删除
删除原有的外键
alter table students drop foreign key FK_STUDENTS_CLASSES;
重新添加外键,并设置级联修改和级联删除
alter table students add constraint FK_STUDENTS_CLASSES foreign key(cid) references classes(class_id) ON UPDATE CASCADE ON DELETE CASCADE;
2、测试级联修改将classes 中的class_name =java2020 的class_id 由 5 改成12022001 李四 男 19 5
2022002 张三 男 18
22022003 王五 女 17 3
2022004 mike 男 17 4
2022005 小z 女 20 5
2022006 小y 女 21 5
执行:update classes set class_id =1 where class_name='java2020';
结果:
classes表
1 java2020 ...
2 java2021 ...
3 java2022 ...
4 java2023 ...
students 表自动的修改了。
2022001 李四 男 19 1
2022002 张三 男 18
22022003 王五 女 17 3
2022004 mike 男 17 4
2022005 小z 女 20 1
2022006 小y 女 21 1
3、测试级联删除
删除class_id=1的班级信息,学生表中引用此班级信息的记录也会被同步删除delete from classes class_id=1;连接查询通过对DQL的学习,我们可以很轻松的从一张数据表中查询出需要的数据;在企业的应用中,我们经常需要从多张表中查询数据(例如:我们查询学生信息的时候需要同事查询学生的班级信息),可以通过连接查询从多张数据表提取数据。
在mysql 中可以使用join 实现多表的联合查询
---连接查询,join按照其功能不同分为三个操作:
inner join 内连接
left join 左连接
right join 右连接
数据准备创建数据表创建班级信息表和学生信息表
CREATE TABLE `classes` (
`class_id` int NOT NULL AUTO_INCREMENT,
`class_name` varchar(40) NOT NULL,
`class_remark` varchar(200) DEFAULT NULL,
PRIMARY KEY (`class_id`), UNIQUE KEY `class_name` (`class_name`)) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
CREATE TABLE `students` (
`stu_num` char(8) NOT NULL,
`stu_name` varchar(20) NOT NULL,
`stu_gender` char(2) NOT NULL,
`stu_age` int NOT NULL,
`cid` int DEFAULT NULL,
PRIMARY KEY (`stu_num`), KEY `FK_STUDENTS_CLASSES` (`cid`), CONSTRAINT `FK_STUDENTS_CLASSES` FOREIGN KEY (`cid`) REFERENCES `classes` (`class_id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、添加数据添加班级表的信息
insert into classes(class_name,class_remark) values('java2020','...');
insert into classes(class_name,class_remark) values('java2021','...');
insert into classes(class_name,class_remark) values('java2022','...');
insert into classes(class_name,class_remark) values('java2023','...');
添加学生表的信息
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('2022001','李四','男',19,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('2022005','小z','女',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('2022006','小y','女',21,1);
现有数据表内容:students 数据表:
stu_num stu_name stu_gender stu_age cid
2022001 李四 男 19 1
2022002 张三 男 18
22022003 王五 女 17 3
2022004 mike 男 17 3
2022005 小z 女 20 1
2022006 小y 女 21 1
2022007 小红 女 20
2022008 小蓝 男 20
classes 数据表
class_id class_name class_remark
1 java2020 ...
2 java2021 ...
3 java2022 ...
4 java2023 ...
内连接 INNER JOIN语法
select ... from tableName1 inner join tableName2
执行:select * from students inner join classes ;
产生的数据是students 表中的行数乘以classes 表中的行数笛卡尔积
* 笛卡尔积(A集合&B集合):使用A中的每个记录一次关联B中每个记录,笛卡尔积的总数=A总数*B总数
* 如果直接执行select * from tableName1 inner join tableName2 会获得两种数据表中的数据集合的笛卡尔积(依次使用tableName1表中的每一条记录去匹配tableName2的每一条数据)
内连接条件两张表用inner join 连接查询之后生成的笛卡尔积数据中很多数据都是无意义的,我们如何消除无意义的数据呢?
--添加两张进行连接查询时的条件
* 使用on设置两张表连接查询的配置条件
--使用where 设置过滤条件:先生成笛卡尔积再从笛卡尔积中过滤数据(效率很低)
select * from students inner join classes where students.cid = classes.id;
--使用on 设置连接查询条件:先判断连接条件是否成立,如果成立两张表的数据进行组合生成一条结果记录
select * from students inner join classes on students.cid = classes.id;
* 结果:只获取两种表中匹配条件成立的数据,任何一张表在另一种表如果没有找到对应匹配则不会出现在查询结果中(例如:学生中没有班级信息,班级没有对应的学生)
左连接 LEFT JOIN需求:请查询出所有学生信息,如果学生有对应的班级信息,则将对应的班级信息也查询出来左连接:显示左表中的所有数据,如果在有右表中存在与左边记录满足匹配条件的数据,则进行匹配;如果右表中不存在匹配数据,则显示为NULL
-- 内连接查询select * from students inner join classes on students.cid = classes.class_id;
-- 左连接查询
select * from students left join classes on students.cid = classes.class_id;
-- 右连接查询
select * from students right join classes on students.cid = classes.class_id;
结果显示:
内连接
2022001 李四 男 19 1 1 java2020 ...
2022005 小z 女 20 1 1 java2020 ...
2022006 小y 女 21 1 1 java2020 ...
2022002 张三 男 18 2 2 java2021 ...
2022003 王五 女 17 3 3 java2022 ...
2022004 mike 男 17 3 3 java2022 ...
左连接
2022001 李四 男 19 1 1 java2020 ...
2022002 张三 男 18 2 2 java2021 ...
2022003 王五 女 17 3 3 java2022 ...
2022004 mike 男 17 3 3 java2022 ...
2022005 小z 女 20 1 1 java2020 ...
2022006 小y 女 21 1 1 java2020 ...
2022007 小红 女 20
2022008 小蓝 男 20
右连接
2022001 李四 男 19 1 1 java2020 ...
2022005 小z 女 20 1 1 java2020 ...
2022006 小y 女 21 1 1 java2020 ...
2022002 张三 男 18 2 2 java2021 ...
2022003 王五 女 17 3 3 java2022 ...
2022004 mike 男 17 3 3 java2022 ...
4 java2023 ...
数据表别名如果在连接查询的多张表中存在相同名字的字段,我们可以使用表名.字段名来进行区分,如果表名太长则不便于sql 语句的编写,
我们可以使用数据表别名示例:
select s.*,c.class_namefrom students sinner join classes con s.cid = c.class_id;
子查询/嵌套查询子查询
--先进行一次查询,第一次查询的结果作为第二次查询的源/条件(第二次查询是基于第一次的查询结果进行的)子查询返回单个值-单行单列案例:查询班级名称为‘java2020’班级中的学生信息(只知道班级名称,而不知道班级ID)
* 传统的方式:
-- 传统查询-- 查询java2020班的所有学生信息
-- 1、查询classes.class_name='java2020'对应的class_idselect class_id from classes where class_name ='java2020';-- 2、根据java2020对应的class_id查询对应的学生select * from students where cid = 1;
* 子查询:
-- 子查询
select * from students where cid = (select class_id from classes where class_name ='java2020');子查询返回多个值-多行单列案例
2:查询所有java班级中的学生信息
* 传统的方式:
-- 查询所有java班级中的学生信息
-- a.查询所有java班的班级编号select class_id from classes where class_name like 'java%'
-- b.查询这些班级编号中的学生信息
select * from students where cid=1unionselect * from students where cid=2 union select * from students where cid=3 union select * from students where cid=4;
* 子查询:
-- 子查询
-- 如果子查询返回的结果是多个值(单列多行),条件使用IN /NOT IN
select * from students where cid in (select class_id from classes where class_name like 'java%');
子查询返回多个值-多行多列
案例3:查询cid=1的班级中性别为男的学生信息
-- 查询cid=1的班级中性别为男的学生信息
-- 多条件查询
select * from students where cid=1 and stu_gender='男';
-- 子查询 :先查询cid=1 班级中的所有学生信息,将这些信息作为一个整体虚拟表(多行多列)
-- 在基于这个虚拟表查询性别为男的学生信息('虚拟表'需要别名)
select * from (select * from students where cid=1) t where t.stu_gender='男';