# 3. 语法

# 3.1 DCL (Data Control Language)

# 创建用户

CREATE USER '用户'@'主机' IDENTIFIED BY '密码' [WITH max_user_connection n];
CREATE USER 'hedon'@'192.168.0.%' IDENTIFIED BY 'Hedon123!';

# 查询用户

SELECT user,host FROM mysql.user;

# 删除用户

DROP USER '用户名'@'主机';

# 查看用户权限

SHOW grants for '用户名'@'主机';

# 授权

# MySQL 8.0 以上要求 user 必须要存在才能 GRANT
GRANT 权限1,权限2 ON 数据库名.数据库表名 TO '用户名'@'主机' [WITH GRANT OPTION];

# 收回权限

REVOKE 权限 ON 数据库.数据库表 FROM '用户名'@'主机' ;

# 3.2 DDL (Data Definition Language)

# 数据库

查询数据库

show databases;

查询单个数据库

show create database 数据库名;

新增数据库

create database 数据库名;

切换数据库

use 数据库名;

修改数据库

alter database 数据库名 charset 字符集;

清空数据库

truncate database 数据库名;

删除数据库

drop database 数据库名;

# 数据表

新建表

create table imc_course(
    course_id INT UNSIGNED auto_increment NOT NULL COMMENT '课程ID',
    title VARCHAR(20) NOT NULL DEFAULT '' COMMENT '课程主标题',
    title_desc VARCHAR(50) NOT NULL DEFAULT '' COMMENT '课程副标题',
    type_id SMALLINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '课程方向ID',
    class_id SMALLINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '课程分类ID',
    level_id SMALLINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '课程难度ID',
    online_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '课程上线时间',
    study_cnt INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '学习人数',
    course_time TIME NOT NULL DEFAULT '0:00' COMMENT '课程时长',
    intro VARCHAR(200) NOT NULL DEFAULT '' COMMENT '课程简介',
    info VARCHAR(200) NOT NULL DEFAULT '' COMMENT '学习需知',
    harvest VARCHAR(200) NOT NULL DEFAULT '' COMMENT '课程收获',
    user_id INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '讲师ID',
    main_pic VARCHAR(200) NOT NULL DEFAULT '' COMMENT '课程主图片',
    content_score DECIMAL(3,1) NOT NULL DEFAULT 0.0 COMMENT '内容评分',
    level_score DECIMAL (3,1) NOT NULL DEFAULT 0.0 COMMENT '简单易懂',
    login_score DECIMAL (3,1) NOT NULL DEFAULT 0.0 COMMENT '逻辑清晰',
    score DECIMAL(3,1) NOT NULL DEFAULT 0.0 COMMENT '综合评分',
    PRIMARY KEY (course_id),
    UNIQUE KEY udx_title(title)
)DEFAULT charset=utf8,COMMENT '课程主表'

修改表

alter table

重命名表

rename table 旧表名 TO 新表名;

清空表

truncate table 数据表名;

删除表

drop table [if exists] 数据表名;

# 视图

新建视图

create view view_name
AS
 SELECT 
  #查询语句.....

修改视图

alter view

删除视图

drop view

# 索引

PRIMARY KEY(主键索引)

ALTER TABLE 'table_name' ADD PRIMARY KEY ('column');

UNIQUE KEY(唯一索引)

ALTER TABLE 'table_name' ADD UNIQUE ('column');

INDEX(普通索引)

ALTER TABLE 'table_name' ADD INDEX index_name ('column');

FULLTEXT(全文索引)

ALTER TABLE 'table_name' ADD FULLTEXT ('column');

多列索引

ALTER TABLE 'table_name' ADD INDEX index_name ('column1','column2','column3');

删除索引

drop index

# 3.3 DML(Data Manipulation Language)

# 数据表

插入数据

INSERT INTO 数据表名(字段1,字段2)
VALUES (数据1),(数据2);

INSERT INTO imc_class(class_name)
VALUES ('MYSQL'),('REDIS'),('MONGODB'),('ORACLE');

#当有重复数据段的时候,下面 class_name 是唯一约束,可以使用 ON DUPLICATE KEY UPDATE,会先删除原来的数据,然后插入新的
INSERT INTO imc_class(class_name)
VALUES ('MYSQL')
ON DUPLICATE KEY UPDATE
add_time=CURRENT_TIMESTAMP;

查询数据

  select 
  
  [distinct] 								-------------去重
  
  字段名                     -------------查询什么字段   

  from 表名                  ------------来自什么表

  where     条件语句          ---------条件      # where xxx = null 查不出来,要用 where xxx is (not) null

  group by                   ----------按什么字段分组

  having                     -----------过滤条件

  order by XXX asc(desc)     -------------排序

  limit m,n                  -----------分页(索引从m开始,第一条索引为0,第2条索引为1;n表示每页显示的数据条数)
  • group by

    注意

    group by 必须和聚合函数结合使用。常见聚合函数:sum(), count(), avg(), min(), max() 等。

    group by 后边的分组字段要与 select 后边的字段保持一致。

    如果过滤分组,则使用 having+过滤条件 来完成。

场景:查询每个年级的总人数和班级数量

例如:

select 年级,sum(人数) fromgroup by 年级;
  • having

    having 常常与 group by 一起使用,是对 group by 分组结果再次进行过滤。

    having 相当于 where 语句,但 having 可以包含聚合函数,但 where 不可以。

    例如:

    #例1
    select 学号,sum(成绩) from 成绩表 group by 学号 having sum(成绩)>600#例2
    select class_name, level_name, count(*)
    from imc_course a
    JOIN imc_class b on a.class_id = b.class_id
    JOIN imc_level c on c.level_id = a.level_id
    group by class_name,level_name
    having count(*)>3;
    

内关联

image-20210209234049336
select 字段1,字段2 from TABLEA A inner join TABLEB B on A.Key = B.key;

外关联

左外连接:左边的表不加限制,匹配不到,右表为null —— left outer join

右外连接:右边的表不加限制,匹配不到,左表为null —— right outer join

全外连接:所有两个表中的行都会包含在集合中,如果匹配不上,在各自的对应的位置显示 null ——full outer join

select1.字段名,表2.字段名 from1 left outer join2 on1.字段=2.字段;

举例:查询只存在于 a 表但是不存在于 b 表的数据:

select a.course_id, a.title
from imc_course a
left join imc_chapter b on b.course_id = a.course_id
where b.course_id is null;

image-20210322162333328

如果是join,在没有其他过滤条件的情况下 MySQL 会自动选择小表作为驱动表

删除数据

DELETE [表名] FROM table_name 条件;
# 删除课程表中没有章节信息的课程
DELETE a
FROM imc_course a
LEFT JOIN imc_chapter b ON b.course_id = a.course_id
WHERE b.course_id IS NULL;
# 删除重复数据,只保留 id 最小的
# 删除课程方向表中重复的课程方向,保留方向ID最小的一条,并在方向名称上增加唯一索引
DELETE a
FROM imc_type a
JOIN(
	SELECT type_name,MIN(type_id) AS min_type_id, count(*)
	FROM imc_type
	GROUP BY type_name having count(*)>1
) b ON a.type_name = b.type_name AND a.type_id > min_type_id;

更新数据

UPDATE 表名 SET col1_name = value1, col2_name = value2 [条件];
# 随机推荐10门课程
UPDATE imc_course
SET is_recommand = 1
ORDER BY rand()  #随机函数
LIMIT 10;

# 3.4 TCL(Transaction Control Language)

# 设置事务的隔离级别

SET [PERSIST|SESSION|GLOBAL]
	TRANSACTION ISOLATION LEVEL
{
	READ UNCOMMITTED|
	READ COMMITTED|
	REPEATABLE READ|
	SERIALIZABLE
}

# 事务过程中的一些指令

BEGIN;
# SQL;
[COMMIT;]
[ROLLBACK;]

# 3.5 聚合函数

聚合函数 数目
COUNT(*) / COUNT([distince] col) 计算符合条件的数据行数,distinct 可以去重。
SUM(col_name) 计算表中符合条件的数值列的合计值。
AVG(col_name) 计算表中符合条件的数值列的平均值。
MAX(col_name) 计算表中符合条件的任意列中数据的最大值
MIN(col_name) 计算表中符合条件的任意列中数据的最小值

# COUNT(col)

SELECT COUNT(COLOR='BLUE' OR NULL) AS BLUE,COUNT(COLOR='BLACK' OR NULL) AS BLACK FROM TABLE;

# SUM(col_name)

SELECT SUM(IF(COLOR='BLUE',1,0)) AS BLUE,SUM(IF(COLOR='BLACK',1,0)) AS BLACK FROM TABLE;

# MAX(col_name)

  • 查询学习人数最多的课程
select title,study_cnt 
from imc_course
where study_cnt = (
  	select MAX(study_cnt) 
  	from imc_course
);

# 3.6 时间函数

函数名 说明
CURDATE() / CURTIME() 返回当前日期 / 返回当前时间
NOW() 返回当前日期和时间
DATE_FORMAT(date,fmt) 按照 fmt 的格式,对日期 date 进行格式化
%Y:四位的年
%m:月份(00..12)
%d:天(00..31)
%H:小时(00..24)
%i:分钟(00..59)
%s:秒(00..59)
SEC_TO_TIME(seconds) 把秒数转换为(小时:分:秒)
TIME_TO_SEC(time) 把(小时:分:秒)转换为秒数
DATEDIFF(date1,date2) 返回 date1 和 date2 两个日期相差的天数
DATE_ADD(date,INITERVAL expr unit) 对给定的日期增加或减少指定的时间单元(unti:DAY天/HOUR小时/MINUTES分钟/SECONDS秒)
EXTRACT(unit FROM date) 提取日期 date 的指定部分
UNIX_TIMESTAMP() 返回 unix 时间戳(从1970年1月1号到当前时间经过的秒数)
FROM_UNIXTIME() 把 unix 时间戳转换为日期时间
CURRENT_TIMESTAMP() 插入数据时自动赋值为当前时间
ON UPDATE CURRENT_TIMESTAMP() 更新数据时自动刷新时间为当前时间
# 格式化当前时间
SELECT DATE_FORMAT(NOW(),'%Y%m%d %H:%i:%s');
# 在当前时间加一天
SELECT NOW(), DATE_ADD(NOW(),INTERVAL 1 DAY);
# 在当前时间减去1小时30分钟
SELECT NOW(), DATE_ADD(NOW(), INTERVAL '-1:30' HOUR_MINUTE);
# 提取日期中的年份/日期
SELECT NOW(), EXTRACT(YEAR FROM NOW()), EXTRACT(DAY FROM NOW());

# 3.7 字符串函数

函数名 说明
CONCAT(str1,str2,...) 把 str1、str2、.. 连接成一个字符串
CONCAT_WS(sep,str1,str2,..) 用指定的分隔符 sep 连接字符串
CHAR_LENGTH(str) 返回字符串 str 的字符个数
LENGTH(str) 返回字符串 str 的字节个数
FORMAT(X,D[,locale]) 将数字字符串 X 格式化为格式,如"#,###,###.##",并舍入到 D 位小数
LEFT(str,len) / RIGHT(str,len) 从字符串的左/右边起返回 len 长度的子字符串
SUBSTRING(str,pos,[len]) 从字符串 str 的 pos 位置起(从1开始)返回长度为 len 的子串
SUBSTRING_INDEX(str,delim,count) 返回字符串 str 按 delim 分割的前 count 个子字符串
LOCATE(substr,str) 在字符串 str 中返回子串 substr 第一次出现的位置(从0开始)
TRIM([remstr FROM] str) 从字符串 str 两端删除不需要的字符 remstr
# 合并字符串
SELECT CONCAT(class_name,title),CONCAT_WS('---',class_name,title)
FROM imc_course a
JOIN imc_class b ON b.class_id = a.class_id;
# 格式化数字
SELECT FORMAT(123456.789,4);
image-20210325165125549

# 3.8 其他函数

函数名 说明
ROUND(X,D) 对数值 X 进行四舍五入保留 D 位小数
RAND() 返回一个在 0 和 1 之间的随机数
CASE WHEN [condition]
THEN result
[WHEN [condition] THEN result ...]
END
case 语句
IF(expr, resIfTure, resIfFalse) if 语句
MD5(str) 返回 str 的MD5 值
# 将男的都是变成女的,女的都变成男的
UPDATE imc_user
SET sex  = (
	CASE 
    WHEN sex = 1 THEN 0 
	ELSE 1
    END
);
上次更新: 8/6/2021, 8:10:03 PM