MYSQL必知必会,详尽入门,一文帮你学会SQL必知必会

目录

前言

数据库的概念和术语

SQL语言和组成

DDL

show :  展示当前已有的数据库或者表

create :创建一个数据库或者一个表 

drop :删除表、数据库对象或者视图

alter :修改现有的数据库对象,例如 修改表的属性或者字段 (列)

DML 

insert :插入记录

update :更新记录

delete :删除记录

DQL

select :从一个或者多个表中检索特定的记录

select 指定列查询

select 条件查询

select 去重查询

select 排序查询 (查询后排序)

select 起别名

select 聚合函数分组查询

select 分页查询

多表理解加基操

多表分类和理解

多表关系分类

一对一关系

一对多关系    (一个班级多个学生, 一个学生对应一个班级)

多对多关系

连表查询   (集合运算)

数据准备

笛卡尔积  (A * B)        

inner join  on

left outer join  on

right outer join  on

子查询 (嵌套查询,合并查询)

总结


前言

  • 各位友友们, 本文可能文章会很长,是小杰对于自己数据库入门基操所学的总结随笔, 是小杰学习数据库以来的一个总和吧, 学会这些数据库的基本的各种操作, 怎删改查基本上是没有什么问题了, 但是基本仅仅也只是适合像小杰一样的数据库入门选手,像查询优化事务, 触发器, SQL语句执行过程等等性能优化方面的东西本文没有涉及, 后序如果小杰学到了也会总结出来跟大家做分享的,  
  • 文章很长,希望友友们可以耐心读下去, 感谢您的阅读,你们的阅读,探讨,分享一直是小杰创作的动力

数据库的概念和术语

  • 按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享 的、统一管理的大量数据的集合
  • 抓住   长期存储   +   方便管理大量数据   (支持并发访问)  相比磁盘更加快速
  • 数据库:数据库是一些关联表的集合;
  • 数据表:表是数据的矩阵;
  • 列:一列包含相同类型的数据;
  • 行:或者称为记录是一组相关的数据;
  • 主键:主键是唯一的;一个数据表只能包含一个主键;   (primary key 非空去重唯一性) 
  • 外键:外键用来关联两个表,来保证参照完整性;MyISAM存储引擎本身并不支持外键,只起到注 释作用;而innodb完整支持外键;    (foreign key 存储在从表, 从表和主表的关系列,关联列)
  • 复合键:或称组合键;将多个列(字段) 指定为一个索引键;
  • 索引:用于快速访问数据表的数据;索引是对表中的一列或者多列的值进行排序的一种结构;     (抓住. 索引是为了方便排序的一列或多列数据)

SQL语言和组成

  • 用于存取数据以及查询、更新和管理关系数据库系统。SQL是关系数据 库系统的标准语言
  • 抓住一点,  SQL就是用来操作数据库的一门语言就OK,关系型数据库标准语言
  • SQL 命令包含:   DQL、DML、DDL、DCL以及TCL   本文仅介绍实操部分

DDL

  • Data Define Languge - 数据定义语言, 用于定义  数据库,数据表
  • show :  展示当前已有的数据库或者表

  • show databases;     显示所有数据库
show databases;
# 显示所有数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| test               |
| xiaojie            |
+--------------------+
7 rows in set (0.00 sec)
  • show tables;  显示当前选择数据库的所有数据表
use tangyujie;
Database changed
show tables;
Empty set (0.00 sec)
  • use 数据库名称;   指定选择一个数据库, 选择具体的数据库操作
use test;
# 指定选择一个数据库
Database changed
  • create :创建一个数据库或者一个表 

  • create database 数据库名;    不安全的创建一个数据库 (如果表已经存在会报错)
  • 加 if not exists 检测, 如果数据库已存在就不创建,否则创建 (不会报错, 只是提示)
create database if not exists tangyujie;
# 创建tangyujie数据库如果不存在
Query OK, 1 row affected (0.00 sec)

show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| tangyujie          |
| test               |
| xiaojie            |
+--------------------+
8 rows in set (0.00 sec)
  • create table 表名;    不安全的创建一个表 (如果表已经存在会报错)
  • 加 if not exists 检测, 如果数据表已存在就不创建,否则创建  (不会报错, 只是提示)
create table if not exists STU (
	id int,
	name varchar(10),
	age tinyint
) engine = innodb default charset = utf8mb4;

show tables;
+---------------------+
| Tables_in_tangyujie |
+---------------------+
| stu                 |
+---------------------+
1 row in set (0.00 sec)
  • drop :删除表、数据库对象或者视图

  • drop table 表名;        不安全的删除一个表 (如果表不存在会报错)
  • 加上if exists  检测,  如果表不存在不会报错 (会提示waring)
drop table stu;
Query OK, 0 rows affected (0.01 sec)

show tables;
Empty set (0.00 sec)

drop table if exists stu;
Query OK, 0 rows affected, 1 warning (0.00 sec)
  • drop database 数据库名;        不安全的删除一个库 (如果库不存在会报错)
  • 加上if exists  检测,  如果表不存在不会报错 (会提示waring)
  • 注意:删库跑路不是吹出来的,不要轻易使用drop 
drop database tangyujie;
Query OK, 0 rows affected (0.01 sec)

show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| test               |
| xiaojie            |
+--------------------+
7 rows in set (0.00 sec)
  • alter :修改现有的数据库对象,例如 修改表的属性或者字段 (列)

  • desc 数据表名;   展示数据表的表结构
 desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | tinyint(4)  | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
  • alter  table  指定表名 add 新列名 列类型(类型长度); 添加一列字段\
  • 新增一列grade varchar(5); 等级列, 成绩等级
alter table stu add grade varchar(5);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | tinyint(4)  | YES  |     | NULL    |       |
| grade | varchar(5)  | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
  • alter table  指定表名  modify  指定列名(字段)  新的类型(新的长度)    -- 修改类型
  • 将  grade 改为 int 类型的 成绩
alter table stu modify grade int(11);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | tinyint(4)  | YES  |     | NULL    |       |
| grade | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
  • alter  table 指定表名  change  旧的列名  新的列名  新类型(类型长度)  --修改列名+类型
  • 将 grade 列改成  addr 列 类型改成  varchar(10);
alter table stu change grade addr varchar(10);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | tinyint(4)  | YES  |     | NULL    |       |
| addr  | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
  • alter  table  指定表名  drop  指定列名;   -- 将指定列删除
alter table stu drop addr;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | tinyint(4)  | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

DML 

  • Data Manipulate Language - 数据操作语言  (记录的增删改查)
  • insert :插入记录

  • insert  into  指定表(指定列)  values(指定值);
  • 指定插入一条记录 id 1001 name = 孙悟空 age = 100
insert into stu(id, name, age) values(1001, '孙悟空', 100);
Query OK, 1 row affected (0.01 sec)

select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
+------+-----------+------+
1 row in set (0.00 sec)
  • values  赋值顺序需要和指定列顺序保持一致
insert into stu(name, id, age) values('沙和尚', 1002, 100);
Query OK, 1 row affected (0.00 sec)

select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
+------+-----------+------+
2 rows in set (0.00 sec)
  • 不指定列, 默认按照所有列顺序插入 values
insert into stu values(1003, '白龙马', 100);
Query OK, 1 row affected (0.00 sec)

select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
| 1003 | 白龙马    |  100 |
+------+-----------+------+
3 rows in set (0.00 sec)

  • update :更新记录

  • update  表名  set  字段1 = 值1 字段2 = 值2  where 条件指定记录; 
  • 指定设置 id = 1003的 记录 name = 猪八戒  (跟新记录) 
update stu set name = '猪八戒' where id = 1003;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
| 1003 | 猪八戒    |  100 |
+------+-----------+------+
3 rows in set (0.00 sec)

  • delete :删除记录

  • delete from 表名 where 条件指定记录;
  • 指定删除id = 1003的记录
delete from stu where id = 1003;
Query OK, 1 row affected (0.00 sec)

select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
+------+-----------+------+
2 rows in set (0.00 sec)

DQL

  • Data Query Language - 数据查询语言
  • select :从一个或者多个表中检索特定的记录

  • 数据准备
insert into stu values(1003, '猪八戒', 100);
insert into stu values(1004, '白龙马', 100);
insert into stu values(1009, '白骨精', 78);
insert into stu values(1006, '哪吒', 88);
insert into stu values(1004, '观音', 99);
select * from stu;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
| 1003 | 猪八戒    |  100 |
| 1004 | 白龙马    |  100 |
| 1006 | 哪吒      |   88 |
| 1004 | 观音      |   99 |
| 1009 | 白骨精    |   78 |
+------+-----------+------+
7 rows in set (0.00 sec)
  • select 指定列查询

  • select 指定列1, 指定列2, 指定列3...  from 表名; 
  • 指定查询 stu 表中的name + age 列信息
select name, age from stu;
+-----------+------+
| name      | age  |
+-----------+------+
| 孙悟空    |  100 |
| 沙和尚    |  100 |
| 猪八戒    |  100 |
| 白龙马    |  100 |
| 哪吒      |   88 |
| 观音      |   99 |
| 白骨精    |   78 |
+-----------+------+
7 rows in set (0.00 sec)
  • select 条件查询

  • select   *   from  表名   where  条件指定查询记录
  • 条件指定查询 id = 1003的记录 
select * from stu where id = 1003;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1003 | 猪八戒    |  100 |
+------+-----------+------+
1 row in set (0.00 sec)
  • select 去重查询

  • select distinct 指定去重列 from 表名;
  •  按照id号进行去重查询
select id from stu;
+------+
| id   |
+------+
| 1001 |
| 1002 |
| 1003 |
| 1004 |
| 1006 |
| 1004 |
| 1009 |
+------+
7 rows in set (0.00 sec)

select distinct id from stu;
+------+
| id   |
+------+
| 1001 |
| 1002 |
| 1003 |
| 1004 |
| 1006 |
| 1009 |
+------+
6 rows in set (0.00 sec)
  • select 排序查询 (查询后排序)

  • select   *  from  stu  order by    指定列1 排序规则, 指定列2 排序规则;
  • 排序规则:默认升序, asc   指定升序   desc 指定降序
  • 先按照 id 升序排序, id  相同再按照 age 降序排序 
select * from stu order by id asc, age desc;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
| 1003 | 猪八戒    |  100 |
| 1004 | 白龙马    |  100 |
| 1004 | 观音      |   99 |
| 1006 | 哪吒      |   88 |
| 1009 | 白骨精    |   78 |
+------+-----------+------+
7 rows in set (0.00 sec)
  • select 起别名

  • select 指定列1  别名,  指定列2 别名... from stu;
  • 将 age 取个别名为年龄   
select age '年龄', name from stu;
+--------+-----------+
| 年龄   | name      |
+--------+-----------+
|    100 | 孙悟空    |
|    100 | 沙和尚    |
|    100 | 猪八戒    |
|    100 | 白龙马    |
|     88 | 哪吒      |
|     99 | 观音      |
|     78 | 白骨精    |
+--------+-----------+
7 rows in set (0.00 sec)
  • select 聚合函数分组查询

  • select 聚合函数名(指定列) from 表名;  指定对于表每一列进行聚合函数
  • 查询一下表中所有的  age 和  age 最大 最小值
select sum(age) from stu;
+----------+
| sum(age) |
+----------+
|      665 |
+----------+
1 row in set (0.00 sec)

select min(age) from stu;
+----------+
| min(age) |
+----------+
|       78 |
+----------+
1 row in set (0.00 sec)

select max(age) from stu;
+----------+
| max(age) |
+----------+
|      100 |
+----------+
1 row in set (0.00 sec)
  • select    指定分组字段   聚合函数(指定字段)  from  表名  group by 指定分组字段
  • 注意:分组也就意味着去重,一旦分组之后, 就会按照分组列进行去重,
  • 一旦去重之后意味着什么?  我们跟随着去重列一同显示出来的其他列也必须是聚合在一起的
  • 上述这句话必须理解清楚,你想想,分组前是很多行,分组之后进行了去重,记录需要从多条记录压缩成一条记录,也就意味着,我们需要聚合多条记录.
  • 依照age 进行 分组, 将多条记录聚合压缩成分组记录, 名字同组的联在一起,并且统计同组人数
select age, count(*), group_concat(`name`) from stu group by age;
+------+----------+-----------------------------------------+
| age  | count(*) | group_concat(`name`)                    |
+------+----------+-----------------------------------------+
|   78 |        1 | 白骨精                                  |
|   88 |        1 | 哪吒                                    |
|   99 |        1 | 观音                                    |
|  100 |        4 | 孙悟空,沙和尚,猪八戒,白龙马             |
+------+----------+-----------------------------------------+
4 rows in set (0.00 sec)
  • select 分页查询

何为分页    limit n, m;  从 n 条记录开始显示m条记录

  • select   *   from    limit    起始记录数, 每页的记录数 
  • 起始记录数目如何计算, 是每一页的记录数的整数倍
  • eg: 查看第一页的记录,和查看第二页的记录  (每页记录数为3)
select * from stu limit 0,3;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1001 | 孙悟空    |  100 |
| 1002 | 沙和尚    |  100 |
| 1003 | 猪八戒    |  100 |
+------+-----------+------+
3 rows in set (0.00 sec)

select * from stu limit 3,3;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1004 | 白龙马    |  100 |
| 1006 | 哪吒      |   88 |
| 1004 | 观音      |   99 |
+------+-----------+------+
3 rows in set (0.00 sec)

select * from stu limit 6,3;
+------+-----------+------+
| id   | name      | age  |
+------+-----------+------+
| 1009 | 白骨精    |   78 |
+------+-----------+------+
1 row in set (0.00 sec)

如上分别是查看第一页 第二页,第三页的 记录

多表理解加基操

  • 多表分类和理解

  • why:     项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系
  • 多表关系分类

  1. 一对一关系

  • 案例:用户与用户详细的关系  

    关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率    (为避免一张表记录过长的情况,字段太多了就可以进行单表拆分,此时拆分的两个表就是一对一的关系)

 实现:在任意一方加入一个外键,关联另一方的主键,并且设置外键为唯一约束

  1. 一对多关系    (一个班级多个学生, 一个学生对应一个班级)

案例:部门与员工的关系    

关系:一个部门对应多个员工,一个员工对应一个部门

实现:在多的一方建立外键,关联另一方的主键

why ?   我们将部门信息放在员工表中,合并为一个表是不可行吗? 为啥要分开来使用,这样产生的一对多的关系也使得查询等等操作更加复杂.  

不是合在一起不行,而是要分析分开的好处, 一旦分开之后我们会减少很多重复的存储部门信息, 因为存在多个员工对应同一个部门的情形,虽然是多个员工,但是对应的是同样的部门信息,记录,  我们没有必要  重复存储这些部门信息呀,  所以才分表    (理解为什么分表)

  1. 多对多关系

案例:学生与课程的关系

关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

 why 使用中间表,还是降低存储压力,减去不必要的存储,我们可以仅仅使用两列来关联左右两张表,  这样可以避免重复的数据存储    ( 保证数据唯一一份  ) 

全部从避免数据冗余,重复存储相同数据的角度去考虑外键,  中间表  分表的原因

  • 连表查询   (集合运算)

  • 数据准备

# 准备班级表
create table 
if not exists class (
	`id` tinyint,
	`name` varchar(10)
) engine = innodb default charset = utf8mb4;

insert into class
values(1, '重点班');

insert into class
values(2, '重点班');

insert into class 
values(3, '平行班');

insert into class
values(4, '平行班');

# 准备学生表
create table 
if not exists student (
	student_id tinyint primary key,
	name varchar(10),
	age tinyint,
	class_id tinyint
) engine = innodb default charset = utf8mb4;

insert into student
values(10, '张三', 19, 3);

insert into student
values(11, '李四', 20, 2);

insert into student
values(12, '王五', 22, 1);

insert into student
values(13, '赵四', 27, 4);

insert into student
values(14, '麻子', null, 3);

  • 笛卡尔积  (A * B)        

  • 笛卡尔集合运算  A {1, 2, 3}    B  {4, 5, 6}    A✖B  {(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)};
  • select * from A, B;
  • select * from A inner join B;
  • 求取 class 表 和  student表的笛卡尔积
select * from class, student;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    1 | 重点班    |         10 | 张三   |   19 |        3 |
|    2 | 重点班    |         10 | 张三   |   19 |        3 |
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    4 | 平行班    |         10 | 张三   |   19 |        3 |
|    1 | 重点班    |         11 | 李四   |   20 |        2 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    3 | 平行班    |         11 | 李四   |   20 |        2 |
|    4 | 平行班    |         11 | 李四   |   20 |        2 |
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    2 | 重点班    |         12 | 王五   |   22 |        1 |
|    3 | 平行班    |         12 | 王五   |   22 |        1 |
|    4 | 平行班    |         12 | 王五   |   22 |        1 |
|    1 | 重点班    |         13 | 赵四   |   27 |        4 |
|    2 | 重点班    |         13 | 赵四   |   27 |        4 |
|    3 | 平行班    |         13 | 赵四   |   27 |        4 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
|    1 | 重点班    |         14 | 麻子   | NULL |        3 |
|    2 | 重点班    |         14 | 麻子   | NULL |        3 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
|    4 | 平行班    |         14 | 麻子   | NULL |        3 |
+------+-----------+------------+--------+------+----------+
20 rows in set (0.00 sec)
  • 上述存在问题,存在很多错误的记录数据  合并显示 , 这些就是  id 和 class_id 不相等的部分,   class的   id   和  student的  class_id 无法对应起来的记录  
  • 条件约束,消除无效记录
select * from class c, student s where c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
+------+-----------+------------+--------+------+----------+
  • inner join  on

只取两张表有对应关系的记录 

  • select * from A, B where 条件限制(两表关系部分)
select * from class c, student s where c.id = s.class_id;
  • select * from A inner join B on 条件限制(两表关系部分)
select * from class c inner join student s on c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
+------+-----------+------------+--------+------+----------+
5 rows in set (0.00 sec)
  • left outer join  on

 在内连接的基础上保留左表没有对应关系的记录

  • select * from A left outer join B on 条件限制(两表关系部分)
  • 为了方便测试: 我在左表中增添没有对应关系的两条记录:
  • 记录1: 5  平行班
  • 记录2:   6   平民班
insert into class
values(5, '平行班');

insert into class
values(6, '平民班');
select * from class c left outer join student s on c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
|    5 | 平行班    |       NULL | NULL   | NULL |     NULL |
|    6 | 平民班    |       NULL | NULL   | NULL |     NULL |
+------+-----------+------------+--------+------+----------+
7 rows in set (0.00 sec)

select * from class c inner join student s on c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
+------+-----------+------------+--------+------+----------+
5 rows in set (0.00 sec)
# 对比一下发现, 左外连接就是整个左表记录完全显示
# 就算没有关联记录也显示
  • right outer join  on

在内连接的基础上保留右表没有对应关系的记录 

  • select * from A right outer join B on 条件限制(两表关系部分)
  • 为了方便测试: 我在左表中增添没有对应关系的两条记录:
  • 记录1:15 王顺 25 null; 没有对应class_id
  • 记录2:  16 虹猫 30 null; 没有对应class_id
insert into student
values(15, '赵顺', 25, null);

insert into student
values(16, '虹猫', 30, null);
select * from class c right outer join student s on c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
| NULL | NULL      |         15 | 赵顺   |   25 |     NULL |
| NULL | NULL      |         16 | 虹猫   |   30 |     NULL |
+------+-----------+------------+--------+------+----------+
7 rows in set (0.00 sec)

select * from class c inner join student s on c.id = s.class_id;
+------+-----------+------------+--------+------+----------+
| id   | name      | student_id | name   | age  | class_id |
+------+-----------+------------+--------+------+----------+
|    3 | 平行班    |         10 | 张三   |   19 |        3 |
|    2 | 重点班    |         11 | 李四   |   20 |        2 |
|    1 | 重点班    |         12 | 王五   |   22 |        1 |
|    4 | 平行班    |         13 | 赵四   |   27 |        4 |
|    3 | 平行班    |         14 | 麻子   | NULL |        3 |
+------+-----------+------------+--------+------+----------+
5 rows in set (0.00 sec)
# 对比之下right outer join 就是相关记录 
# + 右表多余不相关记录全部显示右表
  • 子查询 (嵌套查询,合并查询)

⼀条select语句结果作为另⼀条select语法⼀部分(查询条件,查询结果,表等)。

  • select ....查询字段 ... from ... 表.. where ... 查询条件
  • eg : 查询   class表中   张三所在班级的总人数.
  1. 分步1: 查询张三所在班级
  2. 分布2:   根据第一步获得的班级查询这个班级的总人数
# 第一步获取张三所在班级
select class_id from student where name = '张三';
+----------+
| class_id |
+----------+
|        3 |
+----------+
1 row in set (0.00 sec)

# 第二步获取张三班级的总人数
select c.id '班级', count(*) '学生人数'
from 
	class c, student s
where 
	c.id = s.class_id && c.id = 3
group by c.id;

+--------+--------------+
| 班级   | 学生人数     |
+--------+--------------+
|      3 |            2 |
+--------+--------------+
1 row in set (0.00 sec)

  • 合并上述查询方式:   
  • 合并方式1:  将 select 查询班级的结果作为条件
  • select ....查询字段 ... from ... 表.. where  条件1 &&  c.id = (select ...) group by...
select c.id '班级', count(*) '学生人数'
from 
	class c, student s
where 
	c.id = s.class_id && 
    c.id = (select class_id from student s where s.name = '张三')
    # select 查询结果当作条件进行子查询, 嵌套查询
group by c.id;
  • 合并方式2:将select 查询班级的结果作为一个新的表进行内连接组合查询
  • select  查询字段  from 表1 (select ...)表2  where ...
  • 从一次select 之后的结果当作表进行内联查询
select c.id '班级', count(*) '学生人数'
from 
	class c, 
	(select * from student stu where stu.name = '张三') s
	# 对于select name = 张三的查询结果别名s 当作新表联合查询
where 
	c.id = s.class_id 
group by c.id;

# 上述是一种子查询的方式,但是并不能获取张三班级人数
# 仅作为一种查询方式而已
  • 总之,将来我们进入公司需要操作的表结构绝对是多表操作,多表查询的时候,多表需要联合查询
  • 内连接  inner join   left outer join  right outer join   都是不同的连接多表的方式
  • 子查询,  我们需要 思考的是  一条select查询的结果可以做另外一条select 查询的条件或者是  子表    (select ...) 作为一个where 条件   或者是一个新的 table 在做一次查询
  • 算是嵌套select 查询      

总结

  • 小杰从最简单的SQL语法和表操作入手,从 DDL(表定义,表结构操作)    DQL (select表查询)    DML (记录的增删改查)着手,总结了近期所学,也算是sql入门的一个精简资料了...      
  • 熟练的掌握理解了上述这些东西,就大致可以算是会操作数据表了
  • 多表查询    将两个表以不同的方式各种形式连接起来联合查询,我们需要不断地积累,根据不同地实际业务场景采取不同地多表查询连接方式    
  • 灵活地嵌套使用  select 语句,   一条select 查询结果可以做条件  还可以做 表进行内连接查询.
  • 应老规矩:简要地总结上述关键字操作

DDL回忆

  • use 数据库; 指定数据库操作
  • show databases;   显示所有数据库  show tables;  显示所有数据表
  • create table 表名;     create database 库名; 新建表 + 库 不安全  加上  if not exists 修饰可避免报错
  • drop  table  表名;      drop  database  库名;  删除表 +  库  不安全  加上 if exists 修饰可避免报错
  • alter table  表名  add/modify/change  列调整;   可以修改表结构
  • alter table 表名  drop 列名;  删除列

DML回忆

  • insert into 表名(指定字段) values(指定值);                    增加记录
  • delete from 表名  where 指定删除记录;                         删除记录
  • update 表名  set 字段 = 值 where 指定跟新记录;           跟新记录

DQL回忆

  • select 指定列 from 表;  (指定列查询)
  • select  distinct 列 from 表; 去重查询列
  • select * from 表 order by 指定排序列 排序规则
  • select   指定分组字段  聚合函数   from 表   where ...   group by 分组字段
  • 聚合函数是为了在分组去重之后压缩多条记录为一条.
  • select * from 表 limit 起始记录数, 每页记录数; 分页查询
  • inner join 内连接    left outer join   right outer join 外连接, 关系部分 + 其中一表独有部分
  • select 查询结果可做条件  +  可以新表再  select 查询   (子查询)

猜你喜欢

转载自blog.csdn.net/weixin_53695360/article/details/123770512