文章目录
Mysql 基础
简介
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS(Relational Database Management System,关系数据库管理系统) 应用软件之一
官方网站:https://www.mysql.com/
Mysql5.7.37下载地址
链接:https://pan.baidu.com/s/1vtNgNYHJkJR-veOMF45DJw?pwd=0qkv
提取码:0qkv图形化界面 : SQLyog 或 Navicat Premium
在MySQL安装目录中找到my.ini文件,修改编码为utf8(Mysql中不需要写-)
#服务端
character-set-server=utf8
collation-server=utf8_general_ci
#客户端
default-character-set=utf8 #默认字符集
废话不多 直接开搞
1、数据库基本命令
注意:mysql不区分大小写
#查看所有数据库
SHOW DATABASES;
#查看所有表
SHOW TABLES
#创建数据库
CREATE DATABASE person;
#指定编码格式
CREATE DATABASE student CHARACTER SET utf8;
#不存在创建 存在不创建
CREATE DATABASE IF NOT EXISTS student;
#修改数据库字符编码
ALTER DATABASE student CHARACTER SET utf8;
#删除数据库
DROP DATABASE studnt;
#查看当前使用的数据库
SELECT DATABASE();
#切换数据库
USE student;
#创建表
CREATE TABLE USER(id VARCHAR(20),NAME VARCHAR(20),age INT)
#删除表
DROP TABLE USER;
#表的详细信息
show create table student
2、基础增删改
创建表:语法格式
create table 表名(
字段1 字段类型,
字段2 字段类型
)
1、首先我们创建一个数据库
CREATE DATABASE person;
2、进入数据库
USE person;
3、创建一个表
CREATE TABLE student(
id int,
name varchar(20),
age int
)CHARACTER SET utf8
增加:语法格式
INSERT INTO 表名(字段1,字段2 ...)values(值1,值2...)
#增加操作 INSERT INTO student (id,name,age) values (1,"张三",30); INSERT INTO student (id,name,age) values (2,"李四",40); INSERT INTO student (id,name,age) values (3,"王五",50);
删除:语法格式
DELETE FROM 表名 where 条件;
#删除id为1的数据 DELETE FROM student where id=1;
修改:语法格式
UPDATE student set 修改字段=修改的值 where 条件
#修改id为2的name值为赵四 UPDATE student set name="赵四" where id=2;
清空表
TRUNCATE TABLE 表名
ALTER (改变) 关键字 ADD MODIFY DROP CHANGE RENAME
#向现有表中添加列 增 ALTER TABLE `subject` ADD gradeId INT; #修改表中的列 修改 ALTER TABLE `subject` MODIFY gradeId VARCHAR(10) #删除字段 删 ALTER TABLE `subject` DROP gradeId #修改字段名和值 改变 ALTER TABLE `subject` CHANGE subid subjustId INT PRIMARY KEY AUTO_INCREMENT COMMENT "学科编号" #修改表名 重命名 ALTER TABLE `subject` RENAME studentJect
3、基础查询
指定编码集创建数据库
CREATE DATABASE Test CHARACTER SET utf8;
指定编码创建表
CREATE TABLE emp( id INT, workon VARCHAR(2), NAME VARCHAR(20), gender VARCHAR(1), age INT, idcard INT(18), wordaddress VARCHAR(20), tntrydate VARCHAR(20)) CHARACTER SET utf8
增加一些数据
INSERT INTO emp (id,workon,NAME,gender,age,idcard,wordaddress,tntrydate) VALUES (1,"1","张三","男",20,41245872301675142,"北京","2022-7-23"), (2,"2","李四","男",30,42686012350146246,"上海","2012-1-20"), (3,"3","王五","男",20,42686012350141546,"上海","2002-8-20"), (4,"4","张飞","男",20,45679865656312244,"郑州","2207-2-09"), (5,"5","张大飞","女",18,4567986589631224,"广州","2007-3-19")
有了表现在开始进行查询
查询语法
select 列名 from 表名
查询整张表 * 代表所有
SELECT * FROM emp;
只查询Name
SELECT NAME FROM emp;
给字段起别名
SELECT wordaddress '工作地址' FROM emp;
查询不重复的地址 DISTINCT(去重)
SELECT DISTINCT wordaddress FROM emp;
4、条件查询
查询age20-30岁
方式一:
where后面跟条件 between and 两者之间
SELECT * FROM emp WHERE age BETWEEN 20 AND 30
方式二:
or代表或
SELECT * FROM emp WHERE age=20 OR age=30
方式三:
关键词:in
SELECT * FROM emp WHERE age IN (20,30)
查询不为空数据 IS NOT NULL
SELECT * FROM emp WHERE idcard !='null'; SELECT * FROM emp WHERE idcard IS NOT NULL;
查询为空的数据 IS NULL
SELECT * FROM emp WHERE idcard IS NULL; SELECT * FROM emp WHERE idcard<=>NULL;
模糊查询 like _站单个字符,%站串
SELECT * FROM emp WHERE tntrydate LIKE'2022-2__4' SELECT * FROM emp WHERE tntrydate LIKE'2022-2%' SELECT * FROM emp WHERE tntrydate LIKE '20%';
5、聚合函数
记录个数 COUNT(*)
SELECT COUNT(*) FROM emp;
平均数 AVG(age)
SELECT AVG(age) FROM emp
最大值 MAX(age)
SELECT MAX(age) FROM emp
最小值 MIN(age)
SELECT MIN(age) FROM emp
总和 SUM(age)
SELECT SUM(age) FROM emp;
6、分组查询
根据性别分组,统计男员工,女员工数量
列名必须和分组名一致 列名后可以加聚合函数
GROUP BY 分组
SELECT gender,COUNT(*) FROM emp GROUP BY gender
根据性别分组 统计男性员工和女性员工的平均年龄
SELECT gender ,AVG(age) FROM emp GROUP BY gender;
查询年龄小于45的员工,并根据工作地址分组,获取员工数量大于2的地址
HAVING 分组之后过滤
SELECT wordaddress,COUNT(*) FROM emp GROUP BY wordaddress HAVING COUNT(*)>=2;
7、排序查询
ORDER BY 以什么什么排序 ASC升序
SELECT * FROM emp ORDER BY age ASC;
DESC降序
SELECT * FROM emp ORDER BY age DESC;
先按年龄升序排序,如果年龄相同,再按照id降序
SELECT * FROM emp ORDER BY age ASC,id DESC
8、分页查询
LIMIT 分页
#查询前三条 默认0-3
SELECT * FROM emp LIMIT 3;
#从第二条索引之后 查询3条数据
SELECT * FROM emp LIMIT 2,3;
9、函数
1、字符函数
拼接字符串 CONCAT
SELECT CONCAT("hello","mysql");
变小写 LOWER
SELECT LOWER(NAME) FROM emp;
变大写 UPPER
SELECT UPPER(NAME) FROM emp;
左填充 LPAD
SELECT LPAD ('01',5,'-')
右填充 RPAD
SELECT RPAD(NAME,10,"6") FROM emp;
去除首位空格 TRIM
SELECT TRIM(NAME) FROM emp;
截取字符串 SUBSTRING 参数2可以写负数
SELECT SUBSTRING(NAME,1,2) FROM emp;
字符串替换 replace
SELECT REPLACE(`FIRST_NAME`,'a','A') FROM `t_employees`
2、数值函数
向上取整 CEIL
SELECT CEIL(id) FROM emp;
向下取整 FLOOR
SELECT FLOOR(id) FROM emp;
取余 MOD
SELECT MOD(id,age) FROM emp;
随机数 RAND()
SELECT RAND();
四舍五入 ROUND 第二个参数表示保留的小数
SELECT ROUND(2.333,0);
小测试:获取一个随机数 四舍五入 在左填充
SELECT LPAD(ROUND(RAND()*100,0),5,1)
3、日期函数
获取当前日期 CURDATE()
SELECT CURDATE()
获取当前时间 CURTIME()
SELECT CURTIME()
获取日期+时间 NOW()
SELECT NOW()
SELECT SYSDATE()
获取年月天周
SELECT YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());
SELECT WEEK(NOW())
DATE_ADD()添加 interval间隔 多少天
SELECT DATE_ADD(NOW(),INTERVAL 70 DAY)
指定时间差 DATEDIFF()两日期差
SELECT DATEDIFF ('2001-01-01','2001-02-02')
4、流程函数
if 为true返回第一个值 false返回第二值
SELECT IF(FALSE,'ok','error')
ifnull 第一个值不为空返回第一个,为空返回第二个
SELECT IFNULL('ok','default')
SELECT IFNULL(NULL,"default")
case when then else end语句
开始 当 就是 其他 结束
1、创建表添加数据
CREATE TABLE score(id INT,NAME VARCHAR(20),math VARCHAR(20),english VARCHAR(20),chinese VARCHAR(20))
INSERT INTO score (id,NAME,math,english,chinese)VALUES
(1,'张三',100,80,100),
(2,"李四",80,50,70),
(3,"王五",80,60,100),
(4,"赵六",10,20,30)
2、查询
SELECT id,NAME ,
(CASE WHEN math>=85 THEN'优秀' WHEN math>=60 THEN'良好' ELSE '不及格' END)'math',
(CASE WHEN english>=85 THEN'优秀'WHEN math>=60 THEN'良好' ELSE'不及格' END)'english',
(CASE WHEN chinese>=85 THEN'优秀'WHEN math>=60 THEN'良好'ELSE'不及格'END)'chinese'
FROM score;
SQL 语句编写顺序
SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组 HAVING 过滤条件 ORDER BY 排序列(asc|desc)LIMIT 起始行,总条数
10、约束
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段数据不为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一,不重复 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束**(8.0.16之后)** | 保证字段满足某一个条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
约束是用在表的字段上
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键自增',
NAME VARCHAR(10) NOT NULL UNIQUE COMMENT '不为空唯一',
age INT CHECK (age>0 && age<=120) COMMENT '检查',
STATUS CHAR(1) DEFAULT '1' COMMENT '默认',
gender CHAR(1) COMMENT '性别'
)COMMENT '用户表';
1、外键约束
部门表
CREATE TABLE dept(
id INT AUTO_INCREMENT PRIMARY KEY COMMENT'ID',
NAME VARCHAR(30) NOT NULL COMMENT'部门名称'
)COMMENT '部门表'
INSERT INTO dept(id,NAME) VALUES (1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'总经办')
员工表
CREATE TABLE emp(
id INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
age INT ,
job VARCHAR(20),
salary INT ,
entrydata DATE ,
managerid INT ,
dept_id INT
)
INSERT INTO emp (NAME,age,job,salary,entrydata,managerid,dept_id) VALUES
("张三",20,"总裁",20000,'2001-01-01',0,5),
("李四",30,"项目经理",18000,'2001-01-01',1,1),
("王五",35,"开发",15000,"2002-01-01",2,1)
添加外键语法格式:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名);
#改变 添加 约束 外键
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY(dept_id) REFERENCES dept(id);
外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性 完整性
删除外键语法格式:
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept_id
2、删除/更新
行为 | 说名 |
---|---|
NO ACTION | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与RESTRICT一致) |
RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与NOACTION一致) |
CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。 |
SET NULL | 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null) |
SET DEFAULT | 父表有变更时,子表将外键列设置成一个默认的值(Innodb不支持) |
语法格式:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段) REFERENCES 主表名(主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;
演示:
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY(dept_id) REFERENCES dept(id) ON UPDATE SET NULL ON DELETE SET NULL
11、多表查询
sqlyang表数据:
链接:https://pan.baidu.com/s/1eKQWAgTslCwDP4nRYGyyFQ?pwd=5w36
提取码:5w36
1、子查询(作为条件判断)
语法格式:
SELECT 列名 FROM 表名 WHERE 条件 (子查询结果)
1.查询工资大于Bruce 的员工信息
# 1.先查询Bruce员工的工资
SELECT `SALARY` FROM `t_employees` WHERE `FIRST_NAME`='Bruce'
# 2.查询所有员工的工资
SELECT `SALARY` FROM `t_employees`
# 3.整合
SELECT `SALARY` FROM `t_employees`
WHERE `SALARY`>(SELECT `SALARY` FROM `t_employees` WHERE `FIRST_NAME`='Bruce')
2、子查询(作为枚举查询条件)
语法格式:
SELECT 列名 FROM 表名 Where 列名 in(子查询结果);
1.查询与名为’King’同一部门的员工信息
# 1.先查询处理king的部门
SELECT `DEPARTMENT_ID` FROM`t_employees` WHERE `LAST_NAME`='King'
# 2.在查询所有员工的部门
SELECT `DEPARTMENT_ID` ,`LAST_NAME` FROM `t_employees`
# 3.合并
SELECT `DEPARTMENT_ID` ,`LAST_NAME`
FROM `t_employees`
WHERE `DEPARTMENT_ID`
IN(SELECT `DEPARTMENT_ID` FROM`t_employees` WHERE `LAST_NAME`='King')
3、当子查询结果集形式为多行单列时可以使用 ANY 或 ALL 关键字
1.工资高于(60部门所有人工资)的员工信息
# 1.查询60号部门所有人的工资
SELECT `DEPARTMENT_ID` , `SALARY` FROM `t_employees` WHERE `DEPARTMENT_ID`=60
# 2.查询所有人的工资
SELECT `DEPARTMENT_ID` , `SALARY` FROM `t_employees`
# 3.合并 ALL()大于所有 (好比大于最大值才输出)max
SELECT `DEPARTMENT_ID` , `SALARY` FROM `t_employees` WHERE `SALARY` > ALL( SELECT `SALARY` FROM `t_employees` WHERE `DEPARTMENT_ID`=60)
# 4.ANY大于一个 (好比大于最小值就输出)min
SELECT `DEPARTMENT_ID` , `SALARY` FROM `t_employees` WHERE `SALARY` > ANY( SELECT `SALARY` FROM `t_employees` WHERE `DEPARTMENT_ID`=60)
12、合并查询
语法格式:
SELECT * FROM 表名 1 UNION SELECT * FROM 表名 2
SELECT * FROM 表名 1 UNION ALL SELECT * FROM 表名 2
扩展:利用现有的表创建一个新表[新表中有旧表的所有数据]
CREATE TABLE `n_departments`
SELECT * FROM `t_departments`
使用 UNION 合并结果集,会去除掉两张表中重复的数据
SELECT * FROM `t_departments`
UNION
SELECT * FROM `n_departments`
注意:合并结果的两张表,列数必须相同,列的数据类型可以不同
合并两张表的结果(不去除重复记录)
SELECT * FROM `t_departments`
UNION ALL
SELECT * FROM `n_departments`
图解:
13、表连接查询
语法格式:
SELECT 列名 FROM 表 1 连接方式 表 2 ON 连接条件
1、内连表查询(INNER JOIN ON) 查询两个或者两个以上的表
内连接查询步骤:
1.查询哪些表
2.确定表连接条件,通常 主表.主键=副表.外键
确定查询条件
确定查询的列
方式一:显式内连接
查询所有有部门的员工信息(不包括没有部门的员工) SQL 标准
SELECT e.*,j.*
FROM `t_employees` e
INNER JOIN t_jobs j
ON e.JOB_ID=j.JOB_ID
inner可以省略
方式二:隐式内连接
SELECT * FROM t_employees,t_jobs
WHERE t_employees.JOB_ID = t_jobs.JOB_ID
三表连接查询
# 3.查询所有员工工号、名字、部门名称、部门所在国家ID
SELECT e.* , d.`DEPARTMENT_NAME`,loc.`LOCATION_ID`
FROM `t_employees` e
INNER JOIN `t_departments` d
ON e.`DEPARTMENT_ID`=d.`DEPARTMENT_ID`
INNER JOIN `t_locations` loc
ON d.`LOCATION_ID`=loc.`LOCATION_ID`
画出来看是不是比较好理解 3表查都会了 那4表5表都不在话下
2.左外连接(LEFT JOIN ON)
#查询所有员工信息,以及所对应的部门名称(没有部门的员工,也在查询结果中,部门名称以NULL 填充)
SELECT e.employee_id , e.first_name , e.salary , d.department_name
FROM t_employees e
LEFT JOIN t_departments d
ON e.department_id = d.department_id;
注意:左外连接,是以左表为主表,依次向右匹配,匹配到,返回结果
匹配不到,则返回 NULL 值填充
3、右外连接(RIGHT JOIN ON)
#查询所有部门信息,以及此部门中的所有员工信息(没有员工的部门,也在查询结果中,员工信息以NULL 填充)
SELECT e.employee_id , e.first_name , e.salary , d.department_name FROM t_employees e
RIGHT JOIN t_departments d
ON e.department_id = d.department_id;
注意:右外连接,是以右表为主表,依次向左匹配,匹配到,返回结果
匹配不到,则返回 NULL 值填充