Mysql(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 数据库的常见概念DB:数据库,存储数据的容器DBMS:数据库管理系统,又称为数据库软件或数据库产品,用于创建或管理DBSQL:结构化查询语言,用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有的主流数据库软件通用的语言

1>.什么是数据库

  • 数据库就是用来存储和管理数据的容器!

容器有哪些:

变量、数组、集合、StringBuider、File等

  • 关系结构模型数据库:使用二维表格来存储数据;MySQL就是关系型数据库


2>. 常见的关系型数据库

  • 关系型数据库存放的都是实体之间的关系,“存储的数据都是 以行和列的形式体现”

Oracle(神喻):甲骨文(最高) DB2:IBM ; SQL Server:微软 ; MySQL:甲骨文;Sybase:赛尔斯


20190808084620476.png20190808084646707.png

3>. 非关系型数据库

20190808084742320.png

4>. 理解数据库

  • 我们现在所说的数据库泛指“关系型数据库管理系统(RDBMS - Relational database management system)”,即“数据库服务器”

20190602091530873.png

2. SQL概述


1>. 什么是sql


SQL(Structured Query Language)是“结构化查询语言”,它是对关系型数据库的操作语言。它可以应用到所有关系型数据库中,例如:MySQL、Oracle、SQL Server等。SQ标准(ANSI/ISO)有:

SQL-92:1992年发布的SQL语言标准;

SQL:1999:1999年发布的SQL语言标签;

SQL:2003:2003年发布的SQL语言标签;

虽然SQL可以用在所有关系型数据库中,
但很多数据库还都有标准之后的一些语法,
我们可以称之为“方言”。例如MySQL中的LIMIT
语句就是MySQL独有的方言,其它数据库都不
支持!当然,Oracle或SQL Server都有自己的方言。


2>. Mysql的语法规范


①. 不区分大小写,但建议关键字大写,表名、列名小写

②. 每条命令最好用分号结尾

③. 每条命令根据需要,可以进行缩进或换行

④. 注释 单行注释:#注释文字 -- 注释文字多行注释:/* 注释文字 */


注意 - - 后有一个空格


3>.分类 [ 掌握 ]


①. DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等;

②. DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据) [ 增、删、改、表记录]

③. DQL(Data Query Language):数据查询语言,用来查询记录(数据)。

④. DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;

20190803111717595.png

3. mysql基本的命令


1>. mysql服务的启动和停止


a. 开启:net start mysql b. 关闭:net stop mysql

2>.mysql服务的登录和退出


登录:mysql -h localhost -P(大写) 3306 -u root -p 或mysql -u root -p

注意:h和localhost、P(大写)和3306、u和root之间空不空格都可以


退出:exit quit

3>.mysql的常用命令


①. 查看当前所有的数据库show databases;


②. 打开指定的库use 库名;


③. 查看当前库的所有表show tables;


④. 查看其它库的所有表show tables from 库名;


⑤. 创建表create table 表名(列名 列类型,列名 列类型)


⑥. 查看表结构desc 表名;


⑦. 查看服务器的版本


a. 登录到mysql服务端select version();


b. 没有登录到mysql服务端mysql --version 或mysql -V


①. DDL

DDL:数据定义语言,用来定义数据库对象:库、表、列等;


4. DDL: 数据定义语言[ 库和表的管理 ]


1>.库的管理:创建、修改、删除


①. 库的创建: create database [if not exists] 库名;


②. 库的删除:drop database [if exists] 库名;


③. 修改数据库编码:


a.alter database 库名 character set utf8

b.create database 数据库名称 character set 字符集名;


④. a. 查询某个数据库的字符集:查询某个数据库的创建语句:show create database 数据库名称; b. 查询所有数据库的名称:show databases;


⑤. a. 查询当前正在使用的数据库名称:select database( ); 使用数据库;b.use 数据库名称; 有用


注意:在Mysql中所有的UTF-8编码都不能使用中间的 ‘ - ’即UTF-8要书写成 UTF8;


#案列:创建库Books
create database If not exists Books;
#更改库的字符集
alter database books character set gbk;
alter database book character set utf8;
#库的删除
drop database if exists books;

20190803113008821.png

2>.数据类型介绍[了解]


数据类型

1.整数类型 :int [ age int ,]

2.浮点型:float(5,2)、double(5,2) 2:小数点后保留两位; 5表示小数位+整数位

3.字符型:char(规定长度的字符)varchar(可变长度的字符)

特点:char(M):可以省略,默认为1。varchar(M):不可以省略

varchar: zhangsan (8个字符) 张三 (2个字符)

4.日期型: [ 用单引号引和双引号都可以 ]

date:只保存日期[yyyy-MM-dd]

time:保存时间[HH:mm:ss]

datetime:保存时期+时间

timestamp:时间戳类型, yyyy-MM-dd HH:mm:ss

重点:如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值


3>. 表的管理:创建、修改、删除[掌握]


①. 表的创建

create table[ if not exists] 表名(

字段名 列的类型[(长度) 列的约束],

字段名 列的类型[(长度) 列的约束],

字段名 列的类型[(长度) 列的约束],

字段名 列的类型[(长度) 列的约束]


②. 表的修改: alter table 表名 add|drop|modify|change column 列名[列的类型 约束]

alter table 表名 character set 字符集名称;


③. 表的删除:drop table[ if exists ] 表名;

#①. 修改列名  COLUMN 可以省略
alter table book change COLUMN publishdate pubDate dateTime;
desc book;
#②. 修改列的类型或约束
alter table book modify column pubDate TIMESTAMP;
#③. 添加新列
alter table author add COLUMN annual double;
desc author;
#④. 删除列
alter table author drop COLUMN annual;
#⑤. 修改表名
alter table author rename to book_author;

4>.表的复制

#仅仅复制表的结构
create table copy like employees;
#复制表的结构+数据
create table copy2
select * from employees;
#仅仅复制某些字段:不要数据
create table copy4
select employee_id  from employees
where 0;

5>. 常见约束


含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确性和可靠性


1. 六大约束


①. Not null:非空,用于保证该字段的值不能为空


②. default:默认,用于保证该字段有默认的值,性别


③. primary key :主键,用于保证该字段的值具有唯一性,并且非空比如,学号,员工编号等


④. unique: 唯一,用于保证该字段的值具有唯一性,可以为空。比如座位号


⑤. check:检测约束[ mysql中不支持 ]


⑥. foreign key:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表关联列的,在从表添加外检约束,用于引用主表中某列的值


比如:学生表的专业编号,员工表的部门编号,员工表的工种编号


2. 添加约束的时机


①.创建表时 ②.修改表时


3. 约束的添加分类:


①.列级约束: 六大约束语法上都支持,但外键约束没有效果


②.表级约束:除了非空和默认,其他都支持


4.添加列级约束

 create database student;
    use student;
    create table stuinfo(
       id int primary key,#主键
       stuName varchar(20) not null,#非空
       gender char(1) CHECK(gender='男' or gender='女'),#检查
       seat int unique,#唯一
       age int default 18,#默认约束
); 
create table major(
id int PRIMARY key,
majorName VARCHAR(20)
);

5. 添加表级约束[ 默认和非空不支持 ]


实际的工作中,一般不写constraint 名称


#语法:[constraint 约束名] 约束类型(字段名)

drop table if exists stuinfo;

drop table if exists major;

create database student;
    use student;
    create table stuinfo(
       id int primary key,#主键
       stuName varchar(20) not null,#非空
       gender char(1) CHECK(gender='男' or gender='女'),#检查
       seat int unique,#唯一
       age int default 18,#默认约束
); 
create table major(
id int PRIMARY key,
majorName VARCHAR(20)
);

6.通用写法[掌握]

create table if not exists stuinfo(
      id int primary key,
      stuname varchar(20) not null,
      sex char(1),
      age int default 18,
      seat int unique,
      majorId int,
      #constraint fk_stuinfo_major foreign key(majorId) references major(id)
      foreign key(majorId) references major(id)
);

20190311134657438.png

7.外键[掌握]

  • ①. 主表关联的列必须是一个key(一般是主键或唯一)
  • ②. 插数据时,先插入主表,再插入从表
  • ③. 删除数据时,先删除从表,再删除主表

20190407095408840.png

8.表修改时删除约束

#表修改时删除约束
#1.删除非空约束
alter table stuinfo modify column stuname varchar(20) null;
#2.删除默认约束
alter table stuinfo modify column age int;
#3.删除唯一
alter table stuinfo drop index seat;
#4.删除主键
alter table stuinfo drop primary key;
alter table stuinfo modify column id int;
#5.删除外键
alter table stuinfo drop foreign key fk_stuinfo_major;
#向表emp2的id列中添加primary key约束(my_emp_id_pk)
alter table emp2 modify column id int primary key;
alter table emp2 add constraint my_emp_id_pk primary key(id)
#3. 向表emp2中添加列dept_id,并在其中定义FOREIGN KEY约束,与之相关联的列是dept2表中的id列。
ALTER TABLE emp2 ADD COLUMN dept_id INT;
ALTER TABLE emp2 ADD CONSTRAINT fk_emp2_dept2 FOREIGN KEY(dept_id) REFERENCES dept2(id);

20190313151533130.png

20190804151343293.png

6>. 练习 [ 重点掌握 ]

20190805135246611.png

use housework;
-- 一对多 多对多练习
#tab_category
create table if not exists tab_category(
 cid int primary key auto_increment,
 cname varchar(20)
);
#tab_route
create table if not exists tab_route(
 rid int primary key auto_increment,
 rname varchar(20),
 price float(5,1),
 rdate timestamp,
 cid int
);
alter table tab_route add foreign key(cid) references tab_category(cid);
#tab_user
create table if not exists tab_user(
 uid int primary key auto_increment,
 username varchar(20)
);
#tab_favorite
create table if not exists tab_favorite(
 rid int,
 date timestamp,
 uid int,
 foreign key(rid) references tab_route(rid),
 constraint kf_user_fav foreign key(uid) references tab_user(uid)
);

20190805135945962.png

②. DML语言[ 插入、修改、删除 ]

DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据);

5. DML语言[ 插入、修改、删除][掌握]

1>.插入insert

  • 语法(一):

①. insert into 表名(列名…)values(值1,…);

②. insert into 表名 values(值1,…);

③. insert into 表名(列名…)values(值1,…),(值2,…);

insert into 表名 values(值1,…),(值2,…);[全列名]

  • 语法(2):insert into 表名 set 列名=值,列名=值,....

1.插入的值的类型要与列的类型一致或兼容

2.列的顺序可以调换

3.列数和值的个数必须一致

4.可以省略列名,默认是所有列,而且列的顺序和表中的顺序一致

#1.插入的值的类型要与列的类型一致或兼容(方式1)
insert into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
values(13,'唐艺昕','女','1990-4-23','18988888',null,2);
#方式一支持插入多行,方式不部支持
insert into beauty VALUES(15,'唐艺','女','1990-4-23','18988888',null,2),(16,'唐昕','女','1990-4-23','18988888',null,2);
# 方式2
insert into beauty set id=14,name='唐智',phone='999';


2>.修改update

  • ①. 修改单表的记录:update 表名 set 列=新值,列=新值....where[删选条件]
  • ②. 修改多表的记录[补充]:

update 表1 别名

inner|left|right join 表2 别名

on 连接条件

set 列=值…

where[删选条件]

#1.修改beauty表中姓唐的女神电话为138998899
update beauty set phone='18774149735' where name like '唐%';
#2.修改张无忌的女朋友的手机号为114
update boys b
inner join beauty be
on b.id=be.boyfriend_id
set phone='114'
where b.boyName='张无忌';

3>. 删除delete


①. delete from 表名 where[删选条件]


②. truncate table 表名;不可以加where,清空表


delete Pk truncate

1.delete 可以加where 条件,truncate不 能加

2.truncate删除,效率高一丢丢

3.假如要删除的表中有自增长列,如果用delete删除后,再插入数据,自增长列的值从断点开始,而truncate删除后,再插入数据,自增长列的值从1开始

4.truncate删除没有返回值,delete删除有返回值

5.truncate删除不能回滚,delete删除可以回滚.

20190808085112625.png

#方式一:delete
#单表的删除:删除手机号以9结尾的女神信息
delete from  beauty where phone like '%9';
#方式二:truncate
truncate table 表名;

③. DQL语言学习

DQL[Data Query Language]: 数据查询语言,用来查询记录

DQL

1.基础查询

  • 语法:select 查询列表 from 表名;

特点:

①.查询的结果是一个虚拟的表格

②.查询列表可以是:表中的字段、常量值、表达式、函数

20190803170717879.png

  • ①. 查询表中单个字段、多个字段、所有字段
SELECT last_name from employees;
SELECT last_name,salary,email FROM employees;
SELECT * FROM employees;

②. 查询常量值:select 100


③. 查询表达式:select 100*98;


④. 查询函数 SELECT VERSION();


⑤. 起别名(AS关键字as可以省略)SELECT 100%98 AS 结果;


⑥. 去重DISTINCT SELECT DISTINCT department_id FROM employees;


⑦. 查询员工名和姓连接成一个字段,并显示为 姓名 concat()

SELECT concat(last_name,first_name) AS 姓名 FROM employees;

  • ⑧. +号的作用:运算符
  • sql中的+号:仅仅只有一个功能:运算符

SELECT 100+99; 两个操作数都是数值型,则做加法运算

SELECT “123”+9; 其中一方为字符型,试图将字符数值转换成数值型

如果转换成功,则继续做加法运算;

如果转换失败,则将字符型数值转换成0

select null+10,只要有一方为null,则结果为nul


2. 条件查询


语法: select 查询列表 from 表名 where 筛选条件


1>. 按条件表达式筛选


条件运算符:> < = !=(<>:不等于) >= <=

201908031844086.png

2>. 按逻辑表达式筛选

  • 逻辑运算符: and or not
select last_name,salary,commission_pct
      FROM   employees
      WHERE
      salary>=10000 AND salary<=20000;

3>. 模糊查询[like between and / in /is null]

  • ①. like: 一般和通配符搭档使用

通配符: %:任意多个字符,包含0个字符 _:任意单个字符

#案例1:查询员工名中包含字符a的员工信息
SELECT * from employees where last_name like '%a%';
#案列2:查询出员工名中第二个字符为a,第三个字符为v的员工和工资
SELECT last_name,salary from employees where last_name like '_av%'
#案列3:查询员工名中第二个字符为_的员工名
SELECT  last_name from employees where last_name like '_$_%' ESCAPE '$';

②. between and:select * from employees where employee_id BETWEEN 100 and 120;

a. 使用between and可以提高语句的简洁度

b.包含两个临界值

c.两个临界值不要调换顺序


③. in关键字 in [ 类型一样,类型一样 ]

含义:判断某字段的值是否属于in列表中的某一项

查询员工的工种编号是:IT_prog、 AD_VD、AD_PRES中的一个员工名和工种编号:select last_name,job_id from employees where job_id IN('IT_prog','AD_VD','AD_PRES');


④. is null 和 is not null

 查询没有奖金和员工名和奖金率
    select last_name,commission_pct from employees
    where commission_pct is null;
    查询有奖金和员工名和奖金率
    select last_name,commission_pct from employees 
    where commission_pct is NOT null;

20190803185009679.png

3. 排序查询

语法:select 查询列表 from 表[where 筛选条件]

order by 排序列表 [asc(升序/降序:desc)]

  • ①. order by子句中可以支持单个字段、多个字段、表达式、函数、别名
  • ②. order by 子句一般是放在查询语句的最后面,limit子句除外
  • ③. 默认是升序

注意:如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件

442973b73746a8a14d3b3bb60839a5f6_20190804093833686.png

#按员工信息,要求工资从高到低排序
select * from employees order by salary desc;
#按员工信息,要求工资从低到高排序
select * from employees ORDER BY salary asc;
select * from employees ORDER BY salary;
#查询部门编号>=90的员工信息,按入职时间的先后进行排序[添加筛选条件]
select * 
from employees
where department_id >=90t
ORDER BY hiredate asc;
#按年薪的高低显示员工的信息和年薪[按表达式排序]
select *,salary*12*(1+IFNULL(commission_pct,0)) as 年薪
from employeesT
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) desc;
#按姓名的长度显示员工的姓名和工资
select LENGTH(last_name) 字节长度,last_name,salary
from employees
order by LENGTH(last_name) DESC;
#查询员工信息,要求先按工资升序排序,再按照员工编号排序降序[按多个字段排序]
select * FROM employees
ORDER BY salary asc,employee_id DESC;
#查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序
select *,LENGTH(email) from employees
where email like '%a%'
ORDER BY LENGTH(email) asc,department_id DESC;

常见函数介绍

调用:slect 函数名 (实参列表) [from 表]

分类:

①. 单行函数 concat( ) length( ) ifnull( )

②. 分组函数:做统计使用

1>. 单行函数


1. 字符函数


①. LENGTH(str):获取参数值的字节个数select LENGTH('join');


②. CONCAT(str1,str2,…):拼接字符select concat('aa','bb');


③.upper():大写 LOWER():小写

#将姓变大写,名变小写,然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 from employees;
  • ④. substr() substring():截取从这个字符开始
#注意:索引从1开始   
select substr('我有一个弟弟',2);#有一个弟弟
#截取从指定索引处指定字符长度
select substring('我有一个弟弟',2,4);#有一个弟

2. 数字函数


①. round : 四舍五入

SELECT round(1.45);#round(1.567,2):小数点后保留两位


②. ceil:向上取整


③. floor: 向下取整


3. 日期函数


now():返回当前系统日期+时间

4. 其他函数

#select version();
#select database();
#1.显示系统时间(注意:日期+时间)
select now();
#2.查询员工号 、姓名 、工资,以及工资提高百分之20%后的结果
select employee_id,last_name,salary*1.2  from employees;
#3.将员工的姓名按首字母排序,并写出姓名的长度
select LENGTH(last_name) 长度,substr(last_name,1,1) as 首字符,last_name
from employees
order by 首字符;

2>. 分组函数


分类 : 求和、avg平均值、max最大值、min最小值、count计算个数

这五个参数支持哪些类型

1.sum、avg一般只处理数值型;max、min、count可以处理任何类型

2.以上的分组函数都忽略null值

3.和distinct搭档 五个都使用

4.一般使用count(*)统计行数

5.和分组函数一同查询的字段是group by后的字段


注意:聚合函数的计算,排除了null值

解决方案:

①. 选择不包含非空的列进行计算 [ 主键 ]

②. 使用IfNull函数

#1.简单实用  其他四个也试用
select sum(salary) from employees;
#和distinct搭档 五个都使用
SELECT sum(DISTINCT salary),sum(salary) from employees;
#统计个数
SELECT count(*) from employees;//建议使用这个
SELECT count(1) from employees;

练习

#查询公司员工工资的最大值、最小值、平均值、总和
select max(salary) 最大值,min(salary) 最小值,avg(salary) 平均值,sum(salary) 和 from employees;
#查询员工表中的对入职时间和最小入职时间相差的天数
select DATEDIFF(max(hiredate),min(hiredate)) from employees;
#查询部门编号为90的员工个数
select count(*) from employees where department_id=90;

5.分组查询[所有、每个、各个]


select 字段 from 表

where 条件

[GROUP BY 分组的列表]

[having 分组后的筛选 ]

[order by 子句]


①. 分组查询中的筛选条件分为两类

where 和 having的区别:

1.where 在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来

2.where后不可以跟聚合函数,having可以进行聚合函数的判断


②. gourp by 子句支持单个字段分组,多个字段分组(多个字段用逗号隔开没有顺序)


③. 也可以添加排序(排序放在整个分组查询的最后)


注意 : 查询列表必须特殊,要求是聚合函数和group by后出现的字段

#1.查询每个工种的最高工资[简单的分组查询]
SELECT max(salary),job_id
from employees  
GROUP BY job_id;
#2.查询每个位置上的部门个数
SELECT count(*) 部门个数
from departments
GROUP BY location_id;
#添加筛选条件
#3.查询邮箱中包含a字符的,每个部门的平均工资
select avg(salary) 平均工资,department_id from employees
where email like '%a%' 
GROUP BY department_id;
#4.查询有奖金的每个领导手下员工的最高工资(掌握)
select sum(salary) 最高工资,manager_id
from employees
where commission_pct is not null
GROUP BY manager_id;
#添加复杂的筛选条件
#5.查询哪个部门的员工个数>2
#(1)查询每个部门的员工个数
select count(*),department_id from employees 
GROUP BY department_id;
#(2)根据(1)的结果进行筛选,查询哪个部门员工个数大于2
#添加分组后的筛选(掌握)
select count(*),department_id from employees 
GROUP BY department_id
having count(*)>2;
#6.查询每个工种有奖金的员工的最高工资>12000的工种编号(job_id)和最高工资(掌握)
#(1)查询每个工种有奖金的员工的最高工资
#(2)根据(1)结果筛选,最高工资>12000
select  max(salary),job_id from employees
where commission_pct is not null
GROUP BY job_id
having max(salary)>12000;
#7.查询领导编号>102的每个领导手低下的最低工资>5000的领导编号的是哪个,以及最低工资
select min(salary) 最低工资,manager_id
from employees
where manager_id>102
GROUP BY manager_id
having min(salary)>5000;
#按表达式函数分组
#8.按员工姓名和长度分组,查询每一个员工的个数,筛选员工个数>5的有哪些?
#(1)查询每个长度的员工个数
SELECT count(*),LENGTH(last_name) len_name from employees
GROUP BY LENGTH(last_name)
having count(*)>5;
#(2)筛选员工个数>5
#按多个字段分组[掌握]
#查询每个部门每个工种的平均工资
SELECT AVG(salary),department_id,job_id
from employees
GROUP BY department_id,job_id
#添加排序
#查询每个部门每个工种的平均工资并且按平均工资的高低显示[掌握]
SELECT AVG(salary),department_id,job_id
from employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) desc;

练习

#查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者员工不计算在内[掌握] 
select min(salary) 最低工资,manager_id from employees
where manager_id is not null
GROUP BY manager_id
having 最低工资>6000;
#查询所有部门编号(department_id),员工数量employee_id和工资平均值,并按平均工资降序
select department_id 部门编号,count(*) 员工数量,avg(salary)
from employees
GROUP BY department_id
ORDER BY avg(salary) desc;

6.分页查询[掌握]

语法:

select 查询列表

from 表

[join type] join 表2

on 连接条件

[where 筛选条件]

[GROUP BY 分组的字段]

[having 分组后的筛选]

[ORDER BY 排序的字段]

limit [offset],size;

offset:开始的索引,每页查询的条数;(起始索引从0开始)

size:要显示的条目个数

特点:

①. limit语句放在查询语句的最后

②. 公式 limit (page-1)*size,size;

SELECT * FROM student LIMIT 0,3; -- 第1页
    SELECT * FROM student LIMIT 3,3; -- 第2页
    SELECT * FROM student LIMIT 6,3; -- 第3页
#1.查询前五条的员工信息
select * from employees limit 0,5;
select * from employees limit 5;
#2.查询第11条到第25条
select * from employees limit 10,15;
#3.有奖金的员工信息,并且工资较高的前10名显示出来 
select salary from employees 
where commission_pct is not null 
ORDER BY salary @desc
limit 0,10;

④. 级联查询

7. 级联查询


语法:更新和删除可以分开写,也可以写在一起

ALTER TABLE 表名 ADD CONSTRAINT 外键名称

FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称)

on update cascade on delete cascade


①. 级联更新:on update cascade

级联更新:当主表中的数据进行了更新后,从表中的数据随着也进行了更新


②. 级联删除:on delete cascade

级联删除:当删除了主表中的数据,从表中的数据也随着消失

use test;
#创建一个员工表
create table if not exists emps(
   id int primary key auto_increment,
   dep_id int,
   name varchar(20),
   age int
);
#创建一个部门表
create table if not exists dep(
   id int primary key auto_increment,
   dep_name varchar(220)
);
#添加约束
alter table emps add  foreign key(dep_id) references dep(id);
alter table emps drop foreign key emps_ibfk_1;
#添加数据
insert into dep values(1,'程序员'),(2,'医生');
insert into emps values(1,1,'唐智',23),(2,1,'唐洋',10),(3,2,'小幸',22);
#查询表
select * from emps;
select * from  dep;
#通过级联更新
alter table emps add 
constraint fk_emps_dep foreign key(dep_id) references dep(id)
on update cascade;
#当我们对部门的id进行更新的时候,会使得员工表emps中的数据也对应更改
update dep set id=5 where id=1;
#通过级联删除
alter table emps add constraint fk_emps_dep 
foreign key(dep_id) references dep(id)
on delete cascade;
#当我们把主表中的的数据1删除掉的时候,这个时候从表与之关联的数据也删除了
delete from dep where id=1;

8. 多表查询


笛卡尔积:有两个集合A,B .取这两个集合的所有组成情况


要完成多表查询,需要消除无用的数据


1>. 内连接可以追加分组、排序sql92标准


隐式内连接:使用where条件消除无用的数据

select 字段 from 表1,表2

where 表1.key=表2.key或非等值条件

and 筛选条件

[GROUP BY 分组的列表]

[having 分组后的筛选 ]

[order by 子句]

注意:为表起了别名,则查询的字段就不能使用原来的表去限定


3145bd75d1d3aeba14b257b1478c0239_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RaODQ1MTk1NDg1,size_16,color_FFFFFF,t_70.png

⑤. SQL 99 连接

2>. sql99 [ 推荐 ]


语法:

select 查询列表

from 表1 别名[连接类型 可以省略]

join 表2 别名

on 连接条件

[where筛选条件]

[group by分组]

[having 筛选条件]


内连接 :[ inner ] join

外连接:

左外:left[outer] join

右外:right[outer] join

全外:full[OUTER] join

#数据的准备
use test;
# 创建部门表
create table dept(
id int primary key auto_increment,
name varchar(20)
);
insert into dept (name) values ('开发部'),('市场部'),('财务部');
# 创建员工表
create table emp (
id int primary key auto_increment,
name varchar(10),
gender char(1), -- 性别
salary double, -- 工资
join_date date, -- 入职日期
dept_id int,
foreign key (dept_id) references dept(id) -- 外键,关联部门表(部门表的主键)
 );
#插入数据
insert into emp(name,gender,salary,join_date,dept_id) values('孙悟空','男',7200,'2013-02-24',1);
insert into emp(name,gender,salary,join_date,dept_id) values('猪八戒','男',3600,'2010-12-02',2);
insert into emp(name,gender,salary,join_date,dept_id) values('唐僧','男',9000,'2008-08-08',2);
insert into emp(name,gender,salary,join_date,dept_id) values('白骨精','女',5000,'2015-10-07',3);
insert into emp(name,gender,salary,join_date,dept_id) values('蜘蛛精','女',4500,'2011-03-14',1);
select * from emp;
select * from dept;

2. 外连接


应用场景:用于查询一个表有,另一个表没有的记录

特点 :

1.外连接的查询结果为主表中的所有记录。

如果从表中有和它匹配的,则显示匹配的值

如果从表中没有和它匹配的,则显示null

外连接查询的结果=内连接结果+主表中有而从表没有的记录

2.左外连接,left join左边的是主表

右外连接,right join右边的是主表

3.左外和右外交换两个表的顺序,可以实现同样的效果

4.全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的


①. 左外连接

语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;

* 查询的是左表所有数据以及其交集部分。

* 例子:

-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT 
  t1.*,t2.`name` 
  FROM emp t1 
  LEFT JOIN dept t2 
  ON t1.`dept_id` = t2.`id`;

f2505fe81bd0edc976d01cb4c2d3eb66_20190304102900581.png

08c850cacc9bcb3b7494e65c2f0eb814_2019030410340229.png

5c2709da44c5127d62bf605c369ceb2a_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RaODQ1MTk1NDg1,size_16,color_FFFFFF,t_70.png

②. 右外连接

语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;

* 查询的是右表所有数据以及其交集部分。

* 例子:

SELECT * FROM dept t2 RIGHT JOIN emp t1 ON t1.dept_id = t2.id;

79959f83f96b00e0cd21d06057dd2cb8_20190304102922166.png

bd9cb13c3a96fb11ae5771652bf5b719_20190304103414852.png

  • ③. 全外连接

b3a31f78538113c5d8090aa784080648_20190304103501683.png

7443c1018b1474fc3a535afb4230ff9b_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RaODQ1MTk1NDg1,size_16,color_FFFFFF,t_70.png

3>. 子查询

1. 什么是子查询

  • 查询中嵌套查询,称嵌套查询为子查询
-- 查询工资最高的员工信息
-- 1 查询最高的工资是多少 9000
SELECT MAX(salary) FROM emp;
-- 2 查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.`salary` = 9000;
-- 一条sql就完成这个操作。子查询
SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);

6596367cd38a753dc00c9f655818d273_20190805110945229.png

2. 子查询不同情况


①. 子查询的结果是单行单列的

子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =


– 查询员工工资小于平均工资的人

SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);


②. 子查询的结果是多行单列的

子查询可以作为条件,使用运算符in来判断

– 查询’财务部’和’市场部’所有的员工信息

SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’;

SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;

– 子查询

SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’);

e06228425163288ff3a842eb0a41ff90_20190806112148404.png

  • ③. 子查询的结果是多行多列的

子查询可以作为一张虚拟表参与查询

-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
select * from emp  e
inner join dept d
on e.dept_id=d.id
where e.`join_date` > '2011-11-11';
-- 内连接
SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
WHERE t1.id = t2.dept_id;

4>. 练习

这6个练习题目要求重点掌握

use test;
-- 部门表
CREATE TABLE dept (
  id INT PRIMARY KEY PRIMARY KEY, -- 部门id
  dname VARCHAR(50), -- 部门名称
  loc VARCHAR(50) -- 部门所在地
);
-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES (10,'教研部','北京'),(20,'学工部','上海'),(30,'销售部','广州'),(40,'财务部','深圳');
-- 职务表,职务名称,职务描述
CREATE TABLE job (
  id INT PRIMARY KEY,
  jname VARCHAR(20),
  description VARCHAR(50)
);
  -- 添加4个职务
  INSERT INTO job (id, jname, description) VALUES
  (1, '董事长', '管理整个公司,接单'),
  (2, '经理', '管理部门员工'),
  (3, '销售员', '向客人推销产品'),
  (4, '文员', '使用办公软件');
-- 员工表
CREATE TABLE emp (
  id INT PRIMARY KEY, -- 员工id
  ename VARCHAR(50), -- 员工姓名
  job_id INT, -- 职务id
  mgr INT , -- 上级领导
  joindate DATE, -- 入职日期
  salary DECIMAL(7,2), -- 工资
  bonus DECIMAL(7,2), -- 奖金
  dept_id INT, -- 所在部门编号
  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);
-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
-- 工资等级表
CREATE TABLE salarygrade (
  grade INT PRIMARY KEY,   -- 级别
  losalary INT,  -- 最低工资
  hisalary INT -- 最高工资
);
-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);

d6ec79efd601c84d28e926eab36af59d_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RaODQ1MTk1NDg1,size_16,color_FFFFFF,t_70.png

-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
select e.id,e.ename,e.salary,d.dname,d.loc 
from emp e
inner join dept d
on e.dept_id=d.id;
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
select  e.id,e.ename,e.salary,d.dname,d.loc,j.jname,j.description
from emp e
inner join dept d on e.dept_id=d.id
inner join job j on e.job_id=j.id;
-- 3.查询员工姓名,工资,工资等级
select e.ename,e.salary,s.*
from emp e 
inner join salarygrade s
on e.salary between s.losalary and s.hisalary;
-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
select 
e.ename,e.salary,
j.jname,j.description,
d.dname,d.loc,
s.*
from emp e
inner join job j on e.job_id=j.id
inner join dept d on e.job_id=j.id
inner join  salarygrade s on e.salary between s.losalary and s.hisalary
-- 5.查询出部门编号、部门名称、部门位置、部门人数
select e.dept_id,d.dname,d.loc,e.total
from (select e.dept_id,count(id) total from emp e group by e.dept_id) e
inner join dept d on e.dept_id=d.id 
-- 使用内连接
select d.*,count(e.id) from dept d 
inner join emp e
on d.id=e.dept_id
group by e.dept_id
-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
select e1.id,e1.ename,e1.mgr ,e2.ename 上级领导
from emp e1
left join  emp e2
on e1.mgr=e2.id
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
SQL 关系型数据库 MySQL
mysql
```sql 使用MySQL查询比数学系所有学生年龄大的学生姓名和所在系。代码如下: use teachingdb; SELECT sname, sdept, birthday FROM student WHERE birthday &lt; ALL (SELECT birthday FROM student WHERE sdept = &#39;数学&#39;); ``` 摘要:该任务是查询比数学系学生年龄大的所有学生信息,包括姓名和所在系。通过在SQL中使用ANY/ALL操作符与子查询结合,这里选用ALL与MAX()函数等效,找出比数学系学生最晚出生日期还要早的所有学生。
36 0
|
6月前
|
SQL 关系型数据库 MySQL
初学mysql
本文档介绍了MYSQL中的表格与键的概念,包括列、行、主键和外键。接着,展示了SQL语法基础,如创建、查看、删除数据库及操作表格。讨论了不同数据类型,如decimal、varchar、blob等。通过示例说明如何添加、删除列,插入、更新和删除数据,以及查询技巧,如使用WHERE、ORDER BY和LIMIT子句。
44 0
|
6月前
|
关系型数据库 MySQL Java
MySQL的问题
MySQL的问题
109 0
|
SQL 关系型数据库 MySQL
盘点一下Mysql中的一些小知识(二)
盘点一下Mysql中的一些小知识(二)
85 0
|
SQL 关系型数据库 MySQL
【必知必会的MySQL知识】②使用MySQL
【必知必会的MySQL知识】②使用MySQL
109 0
【必知必会的MySQL知识】②使用MySQL
|
SQL Oracle NoSQL
《MySQL自传》
我是一只勤劳的小海豚,网名叫MySQL,出生于1995年5月23号,正宗95后,你们可别小看我,我现在可是全世界最流行的开源数据库,全球有800万个实例呢。
1070 2
《MySQL自传》
|
SQL 存储 安全
MySQL详细讲解
MySQL入门教程整理,涉及MySQL初级篇所有知识点。
MySQL详细讲解
|
SQL 关系型数据库 MySQL
MySQL(二)
MySQL(二),一起来学习吧。
MySQL(二)
|
SQL 存储 缓存
MySQL的组成
SQL运行机制概述
139 0
MySQL的组成
|
关系型数据库 MySQL
07_mysql中having的使用_having与where的对比
mysql中having的使用 having与where的对比
180 0
07_mysql中having的使用_having与where的对比