一 DQL高级查询

准备数据

  1. -- DQL语句 单表查询
  2. create database day19;
  3. use day19;
  4. -- 创建表
  5. CREATE TABLE student (
  6. id int,
  7. name varchar(20),
  8. age int,
  9. sex varchar(5),
  10. address varchar(100),
  11. math int,
  12. english int
  13. );
  14. -- 插入记录
  15. INSERT INTO student(id,NAME,age,sex,address,math,english) VALUES
  16. (1,'马云',55,'男','杭州',66,78),
  17. (2,'马化腾',45,'女','深圳',98,87),
  18. (3,'马景涛',55,'男','香港',56,77),
  19. (4,'柳岩',20,'女','湖南',76,65),
  20. (5,'柳青',20,'男','湖南',86,NULL),
  21. (6,'刘德华',57,'男','香港',99,99),
  22. (7,'马德',22,'女','香港',99,99),
  23. (8,'德玛西亚',18,'男','南京',56,65),
  24. (9,'唐僧',25,'男','长安',87,78),
  25. (10,'孙悟空',18,'男','花果山',100,66),
  26. (11,'猪八戒',22,'男','高老庄',58,78),
  27. (12,'沙僧',50,'男','流沙河',77,88),
  28. (13,'白骨精',22,'女','白虎岭',66,66),
  29. (14,'蜘蛛精',23,'女','盘丝洞',88,88);

1.1 排序

  1. 1. 语法:
  2. select ... from 表名 order by 排序列 [asc|desc],排序列 [asc|dex]
  3. asc:升序 (默认值)
  4. desc:降序
  5. 2. 注意:
  6. 多字段排序,后面的排序结果是在前面排序的基础之上
  1. # 排序
  2. -- 查询所有数据,使用年龄降序排序
  3. SELECT * FROM student ORDER BY age DESC;
  4. -- 查询所有数据,在年龄降序排序的基础上,如果年龄相同再以数学成绩降序排序
  5. SELECT * FROM student ORDER BY age DESC,math DESC;

1.2 聚合函数

作用:对一列数据进行计算,返回一个结果,忽略null值

  1. * 语法:
  2. count(列名):统计一列个数
  3. max(列名):求出一列的最大值
  4. min(列名):求出一列的最小值
  5. sum(列名):对一列求和
  6. avg(列名):求出一列的平均值
  1. # 聚合函数
  2. -- 查询学生总数(null值处理)
  3. SELECT COUNT(id) FROM student;
  4. SELECT COUNT(english) FROM student;
  5. SELECT COUNT(*) FROM student;
  6. -- 查询年龄大于40的总数
  7. -- 1.1 查询年龄大于40
  8. SELECT * FROM student WHERE age >40;
  9. -- 1.2 总数
  10. SELECT COUNT(*) FROM student WHERE age >40;
  11. -- 查询数学成绩总分
  12. SELECT SUM(math) FROM student;
  13. -- 查询数学成绩平均分
  14. SELECT AVG(math) FROM student;
  15. -- 查询数学成绩最高分
  16. SELECT MAX(math) FROM student;
  17. -- 查询数学成绩最低分
  18. SELECT MIN(math) FROM student;

1.3 分组

作用:对一列数据进行分组,相同的内容分为一组,通常与聚合函数一起使用,完成统计工作

  1. 1. 语法:
  2. select 分组列 from 表名 group by 分组列 having 分组后的过滤条件;
  3. 2. wherehaving区别
  4. where在分组前进行条件过滤,不支持聚合函数
  5. having在分组后今天条件过滤,支持聚合函数
  1. -- 统计男生和女生各有多少人
  2. -- select count(*) from student where sex ='女'; 我想一条sql语句实现
  3. # 分组
  4. -- 按性别分组
  5. SELECT sex FROM student GROUP BY sex;
  6. -- 查询男女各多少人
  7. SELECT sex,COUNT(*) FROM student GROUP BY sex;
  8. -- 查询年龄大于25岁的人,按性别分组,统计每组的人数
  9. -- 1.1 查询年龄大于25岁的人
  10. SELECT * FROM student WHERE age >25;
  11. -- 1.2 按性别分组
  12. SELECT sex FROM student WHERE age >25 GROUP BY sex;
  13. -- 1.3 统计每组的人数
  14. SELECT sex,COUNT(*) FROM student WHERE age >25 GROUP BY sex;
  15. -- 查询年龄大于25岁的人,按性别分组,统计每组的人数,并只显示性别人数大于2的数据
  16. SELECT sex,COUNT(*) FROM student WHERE age >25 AND COUNT(*) >2 GROUP BY sex; -- 错误
  17. SELECT sex,COUNT(*) FROM student WHERE age >25 GROUP BY sex HAVING COUNT(*)>2; -- 正确

1.4 分页

  1. 1. 语法:
  2. select ... from 表名 limit 开始索引,每页显示个数;
  3. 2. 索引特点:
  4. 所以是从0开始,0也是默认值,可以省略
  5. 3. 分页索引公式:
  6. 索引 = (当前页-1) × 每页个数
  1. # 分页
  2. -- 查询学生表中数据,显示前6
  3. SELECT * FROM student LIMIT 0,6;
  4. SELECT * FROM student LIMIT 6;
  5. -- 查询学生表中数据,从第三条开始显示,显示6
  6. SELECT * FROM student LIMIT 2,6;
  7. -- 模拟百度分页,一页显示5
  8. -- 第一页
  9. SELECT * FROM student LIMIT 0,5;
  10. -- 第二页
  11. SELECT * FROM student LIMIT 5,5;
  12. -- 第三页
  13. SELECT * FROM student LIMIT 10,5;

1.5 知识小结

sql语句执行顺序问题

  1. select * from 表名 where 条件 group by 分组 having 分组后条件 order by 排序 limit 分页;

二 数据库约束

2.1 概述

作用

对表中的数据进行限定,保证数据的正确性、有效性和完整性。

分类

  1. 1. primary key:主键约束【掌握】 要求表中有一个字段 唯一 非空,通常我们使用id作为主键
  2. 2. unique:唯一约束
  3. 3. not null:非空约束
  4. 4. default:默认值
  5. 5. foreign key:外键约束

2.2 实现

2.2.1 主键约束

作用:限定某一列的值非空且唯一, 主键就是表中记录的唯一标识。

  1. 1. 设置主键约束
  2. 1)创建表
  3. create table 表名(
  4. id int primary key,
  5. ...
  6. ...
  7. );
  8. 2)已有表
  9. alter tabe 表名 add primary key(id);
  10. 2. 特点:
  11. 一张表只能有一个主键约束,但是我们可以设置联合主键(多个字段)
  12. 3. 自增器
  13. 1)创建表【掌握】
  14. create table 表名(
  15. id int priamry key auto_increment,
  16. ...
  17. ...
  18. );
  19. 2)特点:自增器起始值为1,可以手动指定
  20. alter table 表名 auto_increment=起始值;
  21. 4. 删除主键约束【忘掉....】
  22. 语法:
  23. alter table 表名 drop primary key;
  24. 1)先移出自增器
  25. alter table stu3 modify id int;
  26. 2)才能删除主键约束
  27. alter table stu3 drop primary key;
  28. 解释:因为只有主键约束才有意义设置自增器...(保证唯一性....)
  1. -- 主键约束
  2. -- student表添加主键约束
  3. ALTER TABLE student ADD PRIMARY KEY(id);
  4. -- 创建表时指定主键约束
  5. CREATE TABLE stu1(
  6. id INT PRIMARY KEY,
  7. `name` VARCHAR(32)
  8. );
  9. -- 插入数据测试
  10. INSERT INTO stu1 VALUES(1,'jack');
  11. -- Duplicate entry '1' for key 'PRIMARY' 错误:主键不能重复
  12. INSERT INTO stu1 VALUES(1,'lucy');
  13. -- Column 'id' cannot be null 错误:主键不能为空
  14. INSERT INTO stu1 VALUES(NULL,'lucy');
  15. -- 我想让name字段,也作为主键使用...
  16. -- Multiple primary key defined -- 错误:主键被重复定义了
  17. ALTER TABLE stu1 ADD PRIMARY KEY(`name`);
  18. -- 联合主键(主键字段完全相同,在进行约束的限定)
  19. CREATE TABLE stu2(
  20. id INT ,
  21. `name` VARCHAR(32),
  22. PRIMARY KEY(id,`name`)
  23. );
  24. -- 插入数据测试
  25. INSERT INTO stu2 VALUES(1,'jack');
  26. INSERT INTO stu2 VALUES(1,'lucy');
  27. -- Duplicate entry '1-lucy' for key 'PRIMARY' 错误
  28. INSERT INTO stu2 VALUES(1,'lucy');
  29. -- 自增器
  30. CREATE TABLE stu3(
  31. id INT PRIMARY KEY AUTO_INCREMENT,
  32. `name` VARCHAR(32)
  33. );
  34. -- 插入数据测试
  35. INSERT INTO stu3 VALUES(1,'jack');
  36. INSERT INTO stu3 VALUES(NULL,'jack');
  37. INSERT INTO stu3 VALUES(3,'jack');
  38. INSERT INTO stu3 VALUES(NULL,'jack');
  39. INSERT INTO stu3 VALUES(10,'jack');
  40. INSERT INTO stu3 VALUES(NULL,'jack');
  41. -- 设置自增器起始值
  42. ALTER TABLE stu3 AUTO_INCREMENT=1000;
  43. INSERT INTO stu3 VALUES(NULL,'jack');
  44. -- delete(橡皮擦) truncat(撕纸) 区别
  45. DELETE FROM stu3;
  46. INSERT INTO stu3 VALUES(NULL,'jack');
  47. TRUNCATE TABLE stu3;
  48. INSERT INTO stu3 VALUES(NULL,'jack');
  49. -- 1)先移出自增器
  50. ALTER TABLE stu3 MODIFY id INT;
  51. -- 2)才能删除主键约束
  52. ALTER TABLE stu3 DROP PRIMARY KEY;

2.2.2 唯一约束

作用:限定某一列的值不能重复,可以出现多个null

  1. 1. 创建表时设置唯一约束
  2. create table 表名(
  3. 列名 数据类型 unique,
  4. ...
  5. ...
  6. );
  1. -- 唯一约束
  2. CREATE TABLE stu4(
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. `name` VARCHAR(32) UNIQUE
  5. );
  6. INSERT INTO stu4 VALUES(1,'jack');
  7. -- Duplicate entry 'jack' for key 'name' 错误:名称重复了
  8. INSERT INTO stu4 VALUES(2,'jack');
  9. INSERT INTO stu4 VALUES(3,NULL);
  10. INSERT INTO stu4 VALUES(4,NULL);

2.2.3 非空约束

作用:限定某一列的值不能为null

  1. 1. 创建表时设置非空约束
  2. create table 表名(
  3. 列名 数据类型 not null,-- 非空约束
  4. 列名 数据类型 unique not null,-- (唯一+非空)
  5. );

疑问:唯一 + 非空 = 主键?? 回答:不等于,主键约束一张表只能有一个,唯一+非空 设置多个

  1. -- 唯一+非空
  2. CREATE TABLE stu5(
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. `name` VARCHAR(32) UNIQUE NOT NULL
  5. );
  6. INSERT INTO stu5 VALUES(1,'jack');
  7. -- Column 'name' cannot be null 错误:名称不能为空
  8. INSERT INTO stu5 VALUES(2,NULL);

2.2.4 默认值

作用:限定某一列的默认值,再没有指定的情况下所有列的默认值为null

  1. 1. 创建表设置默认值
  2. create table 表名(
  3. 列名 数据类型 default 默认值,
  4. ...
  5. ...
  6. );
  1. -- 默认值
  2. CREATE TABLE stu6(
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. `name` VARCHAR(32),
  5. sex VARCHAR(5) DEFAULT '男'
  6. );
  7. INSERT INTO stu6(id,`name`) VALUES(1,'小张');
  8. INSERT INTO stu6(id,`name`,sex) VALUES(2,'小刘','女');
  9. -- 因为我们指定了默认值为男,你再插入null,会把默认值覆盖...
  10. INSERT INTO stu6 VALUES(3,'小王',NULL);

三 表关系【重中之重】

3.1 概述

现实生活中,(班级)实体与(学生)实体之间肯定是有关系的,那么我们在设计表的时候,就应该体现出(班级)表与(学生)表之间的这种关系!

简称:关系型数据库(Relation DBMS)

  1. 1. 一对多
  2. 应用场景:
  3. 班级和学生、部门和员工
  4. 解释:
  5. 一个班级下面有多名同学,多名同学属于某一个班级
  6. 2. 多对多
  7. 应用场景:
  8. 老师和学生、学生和课程
  9. 解释:
  10. 一名老师可以教导多名学生,一名学生可以被多个老师教导
  11. 3. 一对一
  12. 应用场景:
  13. 公民和身份证号、公司和注册地
  14. 解释:
  15. 一个公民只能有一个身份证号,一个身份证号对应一个公民

3.2 实现

3.2.1 一对多

  1. * 举例:班级和学生

1588132385848.png

  1. -- 创建新库
  2. CREATE DATABASE day19_pro;
  3. USE day19_pro;
  4. -- 一对多
  5. -- 班级表(主表)
  6. CREATE TABLE class(
  7. id INT PRIMARY KEY AUTO_INCREMENT,
  8. `name` VARCHAR(32)
  9. );
  10. INSERT INTO class VALUES(1,'java一班');
  11. INSERT INTO class VALUES(2,'java二班');
  12. -- 学生表(从表)
  13. CREATE TABLE student(
  14. id INT PRIMARY KEY AUTO_INCREMENT,
  15. `name` VARCHAR(32),
  16. class_id INT -- 外键字段
  17. );
  18. INSERT INTO student VALUES(1,'流川枫',1);
  19. INSERT INTO student VALUES(2,'樱木花道',1);
  20. INSERT INTO student VALUES(3,'大猩猩',2);
  21. INSERT INTO student VALUES(4,'赤木晴子',2);
  22. -- 通过班级找学生
  23. SELECT * FROM student WHERE class_id =1;
  24. -- 通过学生找班级
  25. SELECT * FROM class WHERE id = 2;
  26. -- 给学生表添加外键约束
  27. ALTER TABLE student ADD CONSTRAINT class_id_fk FOREIGN KEY(class_id) REFERENCES class(id);
  28. -- 删除学生表的外键约束
  29. ALTER TABLE student DROP FOREIGN KEY class_id_fk;

3.2.2 多对多

  1. * 举例:学生和课程

1588142266257.png

  1. -- 多对多
  2. -- 课程表(主表)
  3. CREATE TABLE course(
  4. id INT PRIMARY KEY AUTO_INCREMENT,
  5. `name` VARCHAR(32)
  6. );
  7. INSERT INTO course VALUES(1,'java');
  8. INSERT INTO course VALUES(2,'ui');
  9. INSERT INTO course VALUES(3,'美容美发');
  10. INSERT INTO course VALUES(4,'挖掘机');
  11. -- 中间表(从表)
  12. CREATE TABLE sc(
  13. s_id INT,
  14. c_id INT,
  15. PRIMARY KEY(s_id,c_id)
  16. );
  17. INSERT INTO sc VALUES(1,1);
  18. INSERT INTO sc VALUES(1,2);
  19. INSERT INTO sc VALUES(2,1);
  20. INSERT INTO sc VALUES(2,3);
  21. -- 联合主键,可以帮我们校验重复选修问题
  22. INSERT INTO sc VALUES(1,1);
  23. -- 给中间表增加外键约束
  24. ALTER TABLE sc ADD CONSTRAINT s_id_fk FOREIGN KEY(s_id) REFERENCES student(id);
  25. ALTER TABLE sc ADD CONSTRAINT c_id_fk FOREIGN KEY(c_id) REFERENCES course(id);
  26. -- 流川枫不能选修,不存在的课程
  27. INSERT INTO sc VALUES(1,6);

3.2.3 一对一

  • 一对一关系在实际开发中用的并不多,因为可以办关联字段设计在同一张表…
  1. * 公司和注册地

1588143207597.png

  1. -- 一对一
  2. -- 公司表
  3. CREATE TABLE company(
  4. id INT PRIMARY KEY AUTO_INCREMENT,
  5. `name` VARCHAR(32)
  6. );
  7. INSERT INTO company VALUES(1,'拼多多');
  8. INSERT INTO company VALUES(2,'传智播客');
  9. -- 地址表
  10. CREATE TABLE address(
  11. id INT PRIMARY KEY AUTO_INCREMENT, -- 同时也作为外键
  12. `name` VARCHAR(32),
  13. CONSTRAINT id_fk FOREIGN KEY(id) REFERENCES company(id)
  14. );
  15. INSERT INTO address VALUES(1,'上海');
  16. INSERT INTO address VALUES(2,'江苏沭阳');

3.3 外键约束

作用:限定二张表有关系的数据,保证数据的正确性、有效性和完整性

  1. 1. 在从表中添加外键约束
  2. 1)创建表
  3. create table 表名(
  4. 列名 数据类型,
  5. [constraint] [约束名] foreign key(外键列) references 主表(主键)
  6. );
  7. 2)已有表
  8. alter table 表名 add [constraint] [约束名] foreign key(外键列) references 主表(主键);
  9. 2. 外键约束特点
  10. 1)主表不能删除从表已引用的数据
  11. 2)从表不能添加主表未拥有的数据
  12. 3)先添加主表数据再添加从表数据
  13. 4)先删除从表数据再删除主表数据
  14. 5)外键约束允许为空但不能是错的
  15. 3. 删除外键约束
  16. alter table 表名 drop foreign key 约束名;

在企业开发过程中:传统的项目中我们需要外键约束,互联网项目绝对不用……(性能问题)