Mysql -- 基础

SQL

SQL通用语法:

SQL分类:

DDL:

数据库操作

查询:

复制代码
SHOW DATABASES;

创建:

复制代码
CREATE DATABASE[IF NOT EXISTS] 数据库名 [DEFAULT CHARSET字符集] [COLLATE 排序规则];

删除:

复制代码
DROP DATABASE [IF EXISTS] 数据库名;

使用:

复制代码
USE 数据库名;
DDL - 表操作 - 查询:

查询当前数据库所有表

复制代码
SHOW TABLES;

查询表结构:

复制代码
DESC 表名

查询指定表的建表语句:

复制代码
SHOW CREATE TABLE 表名;
DDL - 表操作 - 创建:
DDL - 表操作 - 数据类型
复制代码
create table emp(
    -> id int comment '编号',
    -> workno varchar(10) comment '员工工号',
    -> name varchar(10) comment '姓名',
    -> gender char(1) comment '性别',
    -> age tinyint unsigned comment '年龄',
    -> idcard char(18) comment '身份证号',
    -> entrydate date comment '入职时间'
    -> ) comment '员工表';
DDL - 表操作 - 修改

添加字段:

复制代码
ALTER TABLE 表名 ADD 字段名 类型(长度)[COMMENT 注释][约束];

修改数据类型:

复制代码
ALTER TABLE MODIFY 字段名 新数据类型(长度)

修改字段名和字段类型

复制代码
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度)[COMMENT 注释]

删除字段:

复制代码
ALTER 表名 DROP 字段名;

修改表名:

复制代码
ALTER TABLE 表名 RENAME TO 新表名;
DDL - 表操作 - 删除

删除表

复制代码
DROP TABLE [IF EXISTS] 表名

删除指定表,并重新创建该表

复制代码
TRUNCATE TABLE 表名;

相当于清空

DML:

DML - 添加数据

给指定字段添加数据

复制代码
INSERT INTO 表名(字段1,字段2)VALUES(值1,值2);

给全部字段添加数据

复制代码
INSERT INTO 表名 VALUES(值1,值2);

批量添加数据

复制代码
INSERT INTO 表名(字段1,字段2) VALUES (值1,值2),(值1,值2),(值1,值2);

INSERT INTO 表名 VALUES(值1,值2),(值1,值2);

注:

  • 插入数据时,指定的字段顺序需要与值的顺序是一一对应的
  • 字符串和日期数据应该在包含在引号中
  • 插入的数据应该在范围内
DML - 修改数据
复制代码
UPDATE 表名 SET 字段名1 = 值1,字段名2 = 值2,[WHERE ...]

注:修改语句的条件可以有,也可以没有,如果么有条件,则会修改整张表的所有数据。

DML - 删除数据
复制代码
DELETE FROM 表名 [WHERE 条件];

DQL:

语法:

DQL - 基本查询:

查询多个字段

复制代码
SELECT 字段1,字段2,字段3 ... FROM 表名;
复制代码
SELECT * FROM 表名

设置别名

复制代码
SELECT 字段1 [AS 别名1],字段2 [AS 别名2]... FROM 表名;

去除重复记录

复制代码
SELECT DISTINCT 字段列表 FROM 表名;
DQL - 条件查询:

语法:

复制代码
SELECT 字段列表 FROM 表名 WHERE 条件列表;
复制代码
-- --------------------------------------------------- > 查询需求 <----------------------------------------------

-- 基本查询
-- 1. 查询指定字段 name workno age 返回
select name,workno,age from emp;

-- 2. 查询所有字段返回
select * from emp;

-- 3. 查询所有员工的工作地址,起别名
select workaddress as '工作地址' from emp;

-- 4. 查询公司员工的上班地址(不重复)
select distinct  workaddress '工作地址' from emp;

-- 条件查询
-- A. 查询年龄等于 88 的员工
select * from emp where age = 88;

-- B. 查询年龄小于 20 的员工信息
select * from emp where age <= 20;

-- D. 查询没有身份证号的员工信息
select * from emp where idcard is null;

-- E. 查询有身份证号的员工信息
select * from emp where idcard is not null;

-- F. 查询年龄不等于 88 的员工信息
select * from emp where age <> 88;

-- G. 查询年龄在15岁(包含) 到 20岁(包含)之间的员工信息
select * from emp where age >=15 && age<=20;
select * from emp where age >=15 AND age<=20;
select * from emp where age between 15 and 20; -- between 跟最小值

-- H. 查询性别为 女 且年龄小于 25岁的员工信息
select  * from emp where gender = '女' and age <25;

-- I. 查询年龄等于18 或 20 或 40 的员工信息
select * from emp where age = 18 || age = 20 || age = 40 ;
select * from emp where  age in(18,20,40);

-- J. 查询姓名为两个字的员工信息 _ %
select * from emp where name like '__';

-- K. 查询身份证号最后一位是X的员工信息
select * from emp where idcard  like '%X';

聚合函数:

分组查询:

排序查询:

分页查询:

DQL -聚合函数:

常见聚合函数

语法:

复制代码
SELECT 聚合函数(字段列表) FROM 表名;

注:null值不参与所有聚合函数的运算

复制代码
-- ------------------------------------> 聚合函数--
-- A. 统计该企业员工数量
select count(*) from emp;
select count(idcard) from emp;

-- B. 统计该企业员工的平均年龄
select avg(age) from emp;

-- C. 统计该企业员工的最大年龄
select max(age) from emp;

-- D. 统计该企业员工的最小年龄
select min(age) from emp;

-- E. 统计西安地区员工的年龄之和
select sum(age) from emp where workaddress = '西安';
DQL -分组函数:
复制代码
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];

where 和 having区别

  • 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。

  • 判断条件不同:where不能对聚合函数进行判断,而having可以

    -- 分组查询
    -- A. 根据性别分组 , 统计男性员工 和 女性员工的数量
    select gender,count() from emp group by gender ;
    -- B. 根据性别分组 , 统计男性员工 和 女性员工的平均年龄
    select gender,avg(age) from emp group by gender;
    -- C. 查询年龄小于45的员工 , 并根据工作地址分组 , 获取员工数量大于等于3的工作地址
    select workaddress,count(
    ) address_count from emp where age <45 group by workaddress having address_count >= 3;
    -- D. 统计各个工作地址上班的男性及女性员工的数量
    select workaddress,gender,count(*) '数量' from emp group by gender, workaddress;

  • 执行顺序:where > 聚合函数 > having

  • 分组之后,查询字段一般为聚合函数和分组字段,查询其他字段无任何意义。

DQL -排序查询:

语法:

复制代码
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1,字段2 排序方式2;

排序方式:

  • ASC :升序

  • DESC:降序

    -- 排序查询
    -- A.根据年龄对公司的员工进行升序排序
    select * from emp order by age asc;
    select * from emp order by age desc ;
    -- B. 根据入职时间, 对员工进行降序排序
    select * from emp order by entrydate desc;
    -- C. 根据年龄对公司的员工进行升序排序 , 年龄相同 , 再按照入职时间进行降序排序
    select * from emp order by age asc, entrydate desc;

注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。

DQL -分页查询:

语法:

复制代码
SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;
复制代码
-- 分页查询
-- A. 查询第1页员工数据, 每页展示10条记录
select * from emp limit 10;
-- B. 查询第2页员工数据, 每页展示10条记录 --------> (页码-1)*页展示记录数
select * from emp limit 10,10;
练习:
复制代码
-- 2.6.8 案例
-- 1). 查询年龄为20,21,22,23岁的员工信息。
select * from emp where gender = '女' and age in(20,21,22,23);


-- 2). 查询性别为 男 ,并且年龄在 20-40 岁(含)以内的姓名为三个字的员工。
select * from emp where gender = '男' and (age between 20 and 40) and name like '___';


-- 3). 统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数。
select gender,count(*) from emp where age < 60 group by gender;


-- 4). 查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序。
select name '姓名',age '年龄' from emp where age <= 35 order by age asc,entrydate desc ;


-- 5). 查询性别为男,且年龄在20-40 岁(含)以内的前5个员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序排序。
select * from emp where gender = '男' and (age between 20 and 40)  order by age asc,entrydate desc limit 5;
DQL -执行顺序:

DCL:

DCL - 管理用户:
复制代码
1) 查询用户
select * from mysql.user; 1
2). 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'; 1
3). 修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ; 1
4). 删除用户
DROP USER '用户名'@'主机名' ;

注意事项:

• 在MySQL中需要通过用户名@主机名的方式,来唯一标识一个用户。

DCL- 权限控制

函数

字符串函数

复制代码
--  ----------------------------   函数 ------------------------------- --
-- conccat
select concat('Hello','Mysql');

-- lower
select lower('HEllo');

-- upper
select upper('hello');

-- Lpad
select lpad('01',5,'-');

-- rpad
select rpad('01',5,'-');

-- trim
select trim(' Hello   MySql   ');

-- substring
select substring('Hello  MySQL',1,5);

update emp set workno = lpad(workno,5,'0');

数值函数

常见的数值函数如下:

复制代码
-- 数值函数
-- ceil
select ceil(1.5);

-- floor
select floor(1.1);

-- mod
select mod(3,4);

-- rand
select rand();

-- round
select round(2.345,2);

-- 生成六位随机验证码
select lpad(round(rand() * 1000000,0),6,'0') ;

日期函数

复制代码
-- 日期函数
-- curdate
select curdate();
-- curtime
select curtime();
-- now
select now();

-- Year,MONTH,DAY
select YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());

-- DATE_ADD
SELECT DATE_ADD(NOW(),INTERVAL 70 DAY );

-- DATEDIFF(第一个时间减去第二个时间)
SELECT DATEDIFF('2021-12-01','2021-12-21');

select name,datediff(curdate(),entrydate) as 'entrydays' from emp order by entrydays desc ;

流程函数

复制代码
-- 流程控制函数
-- -- IF
select if(true,'ok','Error');
select if(false,'ok','Error');

-- IFNULL
select ifnull('ok','default'); -- ok
select ifnull(null,'default'); -- default

-- CASE
SELECT
    NAME,
   (CASE workaddress WHEN '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地址'
FROM emp;

-- 案例
select
        id,
       name,
      (case  when math >=85 then '优秀' when math >=60 then '及格' else '不及格' end) '数学' ,
      (case  when english >=85 then '优秀' when english >=60 then '及格' else '不及格' end) '英语' ,
      (case  when chinese >=85 then '优秀' when chinese >=60 then '及格' else '不及格' end) '语文'

from score;

约束

概述:

案例:

根据需求,完成表结构的创建

复制代码
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 '用户表';

 -- 插入数据
 insert into user (name,age,status,gender) values ('程梦雨',19,'1','女'),('Messi',20,'1','男');
外键约束:

外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

语法:
添加外键:
复制代码
CREATE TABLE 表名 (
  字段名  数据类型,
  ...
  [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)
);

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCE 主表(主表列名);

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;
删除/更新行为:

语法:

复制代码
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 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 ;

多表查询:

概述:指从多张表中查询数据

笛卡尔积:两个集合A和集合B的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)

复制代码
-- 多表查询
select * from emp , dept where emp.dept_id = dept.id;
多表查询分类:
连接查询 - 内连接:
复制代码
-- 内连接
-- 1.查询每一个员工的姓名及关联的部门的名称(隐式内连接实现)
select emp.name,dept.name from emp,dept where emp.dept_id = dept.id;

-- 2. 查询每一个员工的姓名,及关联的部门的名称(显式内连接实现)
select emp.name , dept.name from emp inner join dept on emp.dept_id = dept.id;
连接查询 - 外连接:
复制代码
-- 外连接
-- 1. 查询emp标的所有数据,和对应的部门信息(左外)
select emp.* ,d.name from emp left join dept d on d.id = emp.dept_id;

-- 2. 查询dept表的所有数据,和相对应的员工信息(右外)
select d.* , emp.*  from emp right join  dept d on d.id = emp.dept_id;
连接查询 - 子连接:
复制代码
-- 子链接
-- 1. 查询员工及其领导的名字
select e.name , b.name from emp e , emp b where e.managerid = b.id;

-- 2. 查询员工及其领导的名字 ,如果没有领导,也要查询出来
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;
联合查询:
复制代码
-- union all , union
-- 1. 将薪资低于 5000 的员工,和年龄大于50岁的员工共查询出来
select * from emp where salary < 5000
union all
select * from emp where age > 50;

select * from emp where salary < 5000
union
select * from emp where age > 50;
子查询:
标量子查询:(返回单个值)
复制代码
-- 标量子查询
-- 1. 查询"销售部"的所有员工信息
select * from emp where dept_id = (select id from dept where name = '销售部');

-- 2. 查询"房东白"入职之后的员工信息
select entrydate from emp where name = '方东白';

select * from emp where entrydate > (select entrydate from emp where name = '方东白');
列子查询:(返回的结果是一列)
复制代码
-- 列子查询
-- 1. 查询销售部和市场部的所有员工信息
select * from emp where dept_id in (select dept.id from dept where name = '市场部' or name = '销售部');

-- 2. 查询比财务部所有人员工资都高的员工信息
select * from emp where salary > all (select salary from emp where dept_id  = (select id from dept where name = '财务部'));

-- 3. 查询比研发部其中任意一人工资高的员工信息
select salary from emp where dept_id  = (select id from dept where name = '研发部');

select * from emp where salary > any (select salary from emp where dept_id  = (select id from dept where name = '研发部'));
行子查询:
复制代码
-- 行子查询
-- 1. 查询与"张无忌"工资和直属领导相同的信息
select salary , managerid from emp where name = '张无忌';

select * from emp where (salary,managerid) = (select salary , managerid from emp where name = '张无忌');
表子查询:(返回多行多列)
复制代码
-- 表子查询
-- 1. 查询路杖客,宋远桥的职位和薪资相同的员工信息
select salary , job from emp where name = '鹿杖客' or name = '宋远桥';

select * from emp where (job,salary) in (select job, salary  from emp where name = '鹿杖客' or name = '宋远桥');

-- 2.查询入职日期是2006-01-01之后的员工信息及其部门信息
select * from emp where entrydate > '2006-01-01';

select e.* , d.* from (select * from emp where entrydate > '2006-01-01') e  left join dept d on e.dept_id = d.id;
练习:
复制代码
-- 1. 查询员工的姓名、年龄、职位、部门信息 (隐式内连接)
select e.name, e.age,e.job,d.name from emp e join dept d on d.id = e.dept_id;

-- 2. 查询年龄小于30岁的员工的姓名、年龄、职位、部门信息(显式内连接)
select e.name,e.age,e.job,d.name from emp e join dept d on d.id = e.dept_id where e.age < 30;

-- 3. 查询拥有员工的部门ID、部门名称
select distinct d.id,d.name from emp e,dept d where e.dept_id = d.id;

-- 4. 查询所有年龄大于40岁的员工, 及其归属的部门名称; 如果员工没有分配部门, 也需要展示出来
   -- 外连接
   select e.*,d.name from emp e left join dept d on d.id = e.dept_id where e.age > 40;

-- 5. 查询所有员工的工资等级
    -- 表:emp salgrade
    -- 连接条件:emp.salary >= salgrade.losal and emp.salary <= salgrade.hisal
   select e.* ,s.grade from emp e ,salgrade s where e.salary >= s.losal and e.salary <= s.hisal;

-- 6. 查询 "研发部" 所有员工的信息及 工资等级
select e.*, s.grade
from emp e,
     salgrade s
where e.dept_id = (select dept.id from dept where dept.name = '研发部')
  and (e.salary between s.losal and s.hisal);

-- 7. 查询 "研发部" 员工的平均工资
select avg( e.salary) '平均工资' from emp e, dept d where e.dept_id = d.id and d.name = '研发部';

-- 8. 查询工资比 "灭绝" 高的员工信息
select * from emp where salary > (select salary from emp where name = '灭绝');

-- 9. 查询比平均薪资高的员工信息
select avg(salary) from  emp;
select * from emp where salary > (select avg(salary) from emp);


-- 10. 查询低于本部门平均工资的员工信息
select avg(e1.salary) from emp e1 where e1.dept_id = 1;

select *,(select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id) '平均工资' from emp e2 where e2.salary < (select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id);

-- 11. 查询所有的部门信息, 并统计部门的员工人数
select d.id ,d.name, (select count(*) from emp e where e.dept_id = d.id) '人数' from dept d;

select count(*) from emp where dept_id = 1;

-- 12. 查询所有学生的选课情况, 展示出学生名称, 学号, 课程名称
总结:
事务:

事务简介:

复制代码
select @@autocommit;

set @@autocommit = 0; -- 设置手动提交
-- 转账操作
-- 1. 查询张三账户余额
select * from account where name = '张三';

-- 2. 将张三的账户余额 -1000
update account set money = money - 1000 where name = '张三';

程序执行报错...

-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';



-- 提交事务
commit;

-- 回滚事务
rollback;
复制代码
--    ---------------- 方式二 ----------------
begin ;
-- 转账操作
-- 1. 查询张三账户余额
select * from account where name = '张三';

-- 2. 将张三的账户余额 -1000
update account set money = money - 1000 where name = '张三';

程序执行报错...

-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

-- 提交事务
commit ;

-- 回滚事务
rollback ;
事务的四大特性:
并发事务问题:
并发事务的隔离级别:

orcal的默认是 Read committted

事务隔离级别越高,数据效率越低

总结:
相关推荐
GOTXX5 小时前
【Qt】Qt Creator开发基础:项目创建、界面解析与核心概念入门
开发语言·数据库·c++·qt·图形渲染·图形化界面·qt新手入门
猿小喵5 小时前
记录一次TDSQL网关夯住故障
运维·数据库·mysql
电商api接口开发5 小时前
如何在C#中使用LINQ对数据库进行查询操作?
数据库·c#·linq
hnsqls5 小时前
Redis 常问知识
数据库·redis·缓存
经年小栈6 小时前
性能优化-Spring参数配置、数据库连接参数配置、JVM调优
数据库·spring·性能优化
一个小白16 小时前
C++ 用红黑树封装map/set
java·数据库·c++
神奇小永哥6 小时前
redis之缓存雪崩
数据库·redis·缓存
麻花20137 小时前
sql server分析表大小
数据库
纪元A梦8 小时前
Redis最佳实践——秒杀系统设计详解
数据库·redis·缓存
老马啸西风9 小时前
Neo4j GDS-09-neo4j GDS 库中路径搜索算法实现
网络·数据库·算法·云原生·中间件·neo4j·图数据库