文章目录
条件查询
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;
-- 创建student表
CREATE TABLE student (
sid CHAR(6),
sname VARCHAR(50),
age INT,
gender VARCHAR(50) DEFAULT 'male'
);
-- 向student表插入数据
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1007', 'hjop', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1008', 'tyop', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1009', 'nhmk', 13, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1010', 'xdfv', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1012', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1013', 'wang', 15, 'female');
使用关系运算符查询
关系运算符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
-
示例
select * from student where age>=17;
使用IN关键字查询
-
示例一:正向用法
select * from student where sid in ('S_1002','S_1003');
-
示例二:逆向用法
select * from student where sid not in ('S_1001');
使用BETWEEN AND关键字查询
-
示例
select * from student where age between 15 and 18; select * from student where age not between 15 and 18;
使用空值查询
-
示例
insert into student (sid,sname) values ('S_1014', 'alan'); select * from student where age is null;
使用AND关键字查询
-
示例
select * from student where age>15 and gender='male';
使用OR关键字查询
-
示例
select * from student where age>15 or gender='male';
使用LIKE关键字查询(模糊查询)
符号 | 含义 | 示例 |
---|---|---|
% | 包含零个或多个字符的任意字符串 | like’Mc%’ 将搜索以字母 Mc 开头的所有字符串(如McBadden)。 |
_ | 任何单个字符 | like’_heryl’ 将搜索以字母 heryl 结尾的所有六个字母的名称(如Cheryl、Sheryl) |
[] | 指定范围 ([a-f]) 或集合 ([abcdef]) 中的任何单个字符 | like’[M-Z]inger’将搜索以字符串inger结尾、以从M到Z的任何单个字母开头的所有名称(如 Ringer) |
[^] | 不属于指定范围 ([a-f]) 或集合 ([abcdef]) 的任何单个字符 | like’M[^C]’ 将搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如MacFeather) |
* | 它同于DOS命令中的通配符,代表多个字符 | c*c代表cc,cBc,cbc,cabdfec等多个字符 |
? | 同于DOS命令中的?通配符,代表单个字符 | b?b代表brb,bFb等 |
# | 只能代表单个数字 | k#k代表k1k,k8k,k0k |
-
示例
select * from student where sid LIKE '%100%';
使用LIMIT分页查询
-
示例
select * from student order by age asc limit 3;
-
语法格式
-
扩展LIMIT OFFSET
-
分页查询
-
说明
- MySQL分页中开始位置为0,(例如,检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1将检索出第二行而不是第一行)
- OFFSET超过了查询的最大数量并不会报错,而是得到一个空的结果集
使用GROUP BY进行分组查询
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;
-- 创建员工表
CREATE TABLE employee (
id int,
name varchar(50),
salary int,
departmentnumber int
);
-- 向员工表中插入数据
INSERT INTO employee values(1,'tome',2000,1001);
INSERT INTO employee values(2,'lucy',9000,1002);
INSERT INTO employee values(3,'joke',5000,1003);
INSERT INTO employee values(4,'wang',3000,1004);
INSERT INTO employee values(5,'chen',3000,1001);
INSERT INTO employee values(6,'yukt',7000,1002);
INSERT INTO employee values(7,'rett',6000,1003);
INSERT INTO employee values(8,'mujk',4000,1004);
INSERT INTO employee values(9,'poik',3000,1001);
GROUP BY和聚合函数一起使用
-
示例一:统计各门的员工数
select count(*), departmentnumber from employee group by departmentnumber;
-
示例二:统计部门编号大于1001的各部门员工个数 MySQL命令
select count(*), departmentnumber from employee where departmentnumber>1001 group by departmentnumber;
GROUP BY和聚合函数以及HAVING一起使用
-
示例:统计工资总和大于8000的部门
select sum(salary),departmentnumber from employee group by departmentnumber having sum(salary)>8000;
使用ORDER BY对查询结果排序
-
基本语法
SELECT 字段名1,字段名2,… FROM 表名 ORDER BY 字段名1 [ASC 丨 DESC],字段名2 [ASC | DESC]; 字段名1、字段名2是查询结果排序的依据; 参数 ASC表示按照升序排序,DESC表示按照降序排序; 默认情况下,按照ASC方式排序。通常情况下,ORDER BY子句位于整个SELECT语句的末尾。
-
示例:查询所有学生并按照年纪大小升序排列
select * from student order by age asc;
组合查询(UNION、UNION ALL)
-
区别
-
UNION会将组合后的结果进行去重处理
-
UNION ALL会将组合的结果直接拼接,并不进行去重处理
-
-
注意事项
-
组合查询的两张表的内容需要对齐,包括列数需要一致,顺序需要一致;否者直接报错
-
组合查询应避免出现列的字段内容不对应的情况;虽然结果没有抛出异常,但是连接后的表数据错乱,这样的数据已经没有意义了。
-
关于UNION之后的排序,ORDER BY应该写在最后;不是对每部分结果排序,而是对最终结果排序
-
-
示例
-- 导入数据 DROP TABLE IF EXISTS table_a; CREATE TABLE table_a( a_name VARCHAR(8), a_age INT ) ENGINE = InnoDB DEFAULT CHARSET = utf8; INSERT INTO table_a (a_name,a_age) VALUE ('Alice',18) ,('Bob',29) ,('Allen',22) ,('Kitty',27) ,('Jack',23); DROP TABLE IF EXISTS table_b; CREATE TABLE table_b( b_name VARCHAR(8), b_age INT ) ENGINE = InnoDB DEFAULT CHARSET = utf8; INSERT INTO table_b (b_name,b_age) VALUE ('Alice',18) ,('Bob',29) ,('Kevin',30) ,('Anne',24) ,('Jean',29); # 去重的 SELECT * FROM table_a UNION SELECT * FROM table_b; # 不去重的 SELECT * FROM table_a UNION ALL SELECT * FROM table_b;
别名设置(AS)
为表起别名
-
语法格式
SELECT * FROM 表名 [AS] 表的别名 WHERE .... ;
-
示例
select * from student as stu; select * from student stu;
为字段取别名
-
语法格式
SELECT 字段名1 [AS] 别名1 , 字段名2 [AS] 别名2 , ... FROM 表名 WHERE ... ;
-
示例
select sname as '姓名', sid from student;
多表关系
表的关联关系
-
多对一
-
多对多
-
一对一
数据准备
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS class;
-- 创建班级表
CREATE TABLE class(
cid int(4) NOT NULL PRIMARY KEY,
cname varchar(30)
);
-- 创建学生表
CREATE TABLE student(
sid int(8) NOT NULL PRIMARY KEY,
sname varchar(30),
classid int(8) NOT NULL
);
-- 为学生表添加外键约束
ALTER TABLE student ADD CONSTRAINT fk_student_classid FOREIGN KEY(classid) REFERENCES class(cid);
-- 向班级表插入数据
INSERT INTO class(cid,cname)VALUES(1,'Java');
INSERT INTO class(cid,cname)VALUES(2,'Python');
-- 向学生表插入数据
INSERT INTO student(sid,sname,classid)VALUES(1,'tome',1);
INSERT INTO student(sid,sname,classid)VALUES(2,'lucy',1);
INSERT INTO student(sid,sname,classid)VALUES(3,'lili',2);
INSERT INTO student(sid,sname,classid)VALUES(4,'domi',2);
关联查询
select * from student where classid=(select cid from class where cname='Java');
删除外键的数据
在此,请注意:班级表和学生表之间存在关联关系;
要删除Java班级,应该先删除学生表中与该班相关联的学生。否则,假若先删除Java班那么学生表中的cid就失去了关联
delete from student where classid=(select cid from class where cname='Java');
delete from class where cname='Java';
交叉连接查询(CROSS JOIN)
-
语法格式
SELECT * FROM 表1 CROSS JOIN 表2; 在该语法中:CROSS JOIN用于连接两个要查询的表,通过该语句可以查询两个表中所有的数据组合。
内连接查询([INNER] JOIN)
-
语法格式
SELECT 查询字段1,查询字段2, ... FROM 表1 [INNER] JOIN 表2 ON 表1.关系字段=表2.关系字段 INNER JOIN用于连接两个表 ON来指定连接条件 其中INNER可以省略
-
数据准备
-- 若存在数据库mydb则删除 DROP DATABASE IF EXISTS mydb; -- 创建数据库mydb CREATE DATABASE mydb; -- 选择数据库mydb USE mydb; -- 创建部门表 CREATE TABLE department( did int (4) NOT NULL PRIMARY KEY, dname varchar(20) ); -- 创建员工表 CREATE TABLE employee ( eid int (4) NOT NULL PRIMARY KEY, ename varchar (20), eage int (2), departmentid int (4) NOT NULL ); -- 向部门表插入数据 INSERT INTO department VALUES(1001,'财务部'); INSERT INTO department VALUES(1002,'技术部'); INSERT INTO department VALUES(1003,'行政部'); INSERT INTO department VALUES(1004,'生活部'); -- 向员工表插入数据 INSERT INTO employee VALUES(1,'张三',19,1003); INSERT INTO employee VALUES(2,'李四',18,1002); INSERT INTO employee VALUES(3,'王五',20,1001); INSERT INTO employee VALUES(4,'赵六',20,1004);
-
示例:查询员工姓名及其所属部门名称
select employee.ename,department.dname from department inner join employee on department.did=employee.departmentid;
外连接查询(LEFT | RIGHT [OUTER] JOIN)
-
语法格式
SELECT 查询字段1,查询字段2, ... FROM 表1 LEFT | RIGHT [OUTER] JOIN 表2 ON 表1.关系字段=表2.关系字段 WHERE 条件 LEFT | RIGHT [OUTER] JOIN 为关键字 关键字左边的表被称为左表,关键字右边的表被称为右表;OUTER可以省略。 LEFT [OUTER] JOIN 左(外)连接:返回包括左表中的所有记录和右表中符合连接条件的记录。 RIGHT [OUTER] JOIN 右(外)连接:返回包括右表中的所有记录和左表中符合连接条件的记录。 如果表1的某条记录在表2中不存在则在表2中显示为空。
-
数据准备
-- 若存在数据库mydb则删除 DROP DATABASE IF EXISTS mydb; -- 创建数据库mydb CREATE DATABASE mydb; -- 选择数据库mydb USE mydb; -- 创建班级表 CREATE TABLE class( cid int (4) NOT NULL PRIMARY KEY, cname varchar(20) ); -- 创建学生表 CREATE TABLE student ( sid int (4) NOT NULL PRIMARY KEY, sname varchar (20), sage int (2), classid int (4) NOT NULL ); -- 向班级表插入数据 INSERT INTO class VALUES(1001,'Java'); INSERT INTO class VALUES(1002,'C++'); INSERT INTO class VALUES(1003,'Python'); INSERT INTO class VALUES(1004,'PHP'); -- 向学生表插入数据 INSERT INTO student VALUES(1,'张三',20,1001); INSERT INTO student VALUES(2,'李四',21,1002); INSERT INTO student VALUES(3,'王五',24,1002); INSERT INTO student VALUES(4,'赵六',23,1003); INSERT INTO student VALUES(5,'Jack',22,1009); 准备这组数据有一定的特点,为的是让大家直观的看出左连接与右连接的不同之处 1、班级编号为1004的PHP班级没有学生 2、学号为5的学生Jack班级编号为1009,该班级编号并不在班级表中
-
示例一:查询每个班的班级ID、班级名称及该班的所有学生的名字 -> 左(外)连接查询
select class.cid,class.cname,student.sname from class left outer join student on class.cid=student.classid;
1、分别找出Java班、C++班、Python班的学生 2、右表的Jack不满足查询条件故其没有出现在查询结果中 3、虽然左表的PHP班没有学生,但是任然显示了PHP的信息;但是,它对应的学生名字为NULL
-
示例二:查询每个班的班级ID、班级名称及该班的所有学生的名字 -> 右(外)连接查询
select class.cid,class.cname,student.sname from class right outer join student on class.cid=student.classid;
1、分别找出Java班、C++班、Python班的学生 2、左表的PHP班不满足查询条件故其没有出现在查询结果中 3、虽然右表的jack没有对应班级,但是任然显示王跃跃的信息;但是,它对应的班级以及班级编号均为NULL
子查询
数据准备
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS class;
-- 创建班级表
CREATE TABLE class(
cid int (4) NOT NULL PRIMARY KEY,
cname varchar(20)
);
-- 创建学生表
CREATE TABLE student (
sid int (4) NOT NULL PRIMARY KEY,
sname varchar (20),
sage int (2),
classid int (4) NOT NULL
);
-- 向班级表插入数据
INSERT INTO class VALUES(1001,'Java');
INSERT INTO class VALUES(1002,'C++');
INSERT INTO class VALUES(1003,'Python');
INSERT INTO class VALUES(1004,'PHP');
INSERT INTO class VALUES(1005,'Android');
-- 向学生表插入数据
INSERT INTO student VALUES(1,'张三',20,1001);
INSERT INTO student VALUES(2,'李四',21,1002);
INSERT INTO student VALUES(3,'王五',24,1003);
INSERT INTO student VALUES(4,'赵六',23,1004);
INSERT INTO student VALUES(5,'小明',21,1001);
INSERT INTO student VALUES(6,'小红',26,1001);
INSERT INTO student VALUES(7,'小亮',27,1002);
带比较运算符的子查询
-
示例一:查询张三同学所在班级的信息
select * from class where cid=(select classid from student where sname='张三');
-
示例二:查询比张三同学所在班级编号还大的班级的信息
select * from class where cid>(select classid from student where sname='张三');
带EXISTS关键字的子查询
-
示例:假如王五同学在学生表中则从班级表查询所有班级信息
select * from class where exists (select * from student where sname='王五');
带ANY关键字的子查询
-
示例:查询比任一学生所属班级号还大的班级编号
select * from class where cid > any (select classid from student);
带ALL关键字的子查询
-
示例:查询比所有学生所属班级号还大的班级编号
select * from class where cid > all (select classid from student);
总结
-
查询语句的书写顺序和执行顺序
-
查询语句的执行顺序