1. SQL 分类

SQL通用语法

  • 分号结尾

  • 关键字大写

  • 注释 #

DDL

create database if not exists zpp default charset utfmb4;
drop database name;
select database()''

CREATE TABLE user (
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '编号',
    employee_id VARCHAR(10) NOT NULL COMMENT '员工工号',
    name VARCHAR(10) NOT NULL COMMENT '员工姓名',
    gender CHAR(1) NOT NULL COMMENT '性别(男/女)',
    age TINYINT UNSIGNED NOT NULL COMMENT '年龄',
    id_card CHAR(18) NOT NULL COMMENT '身份证号',
    hire_date DATE NOT NULL COMMENT '入职时间'
) COMMENT='员工信息表';

alter table employee add nickname varchar(20) comment '昵称';
alter table employee change nickname username varchar(30) comment '用户名';
alter table employee modify username varchar(50);
alter table employee drop username;
alter table employee rename to emp;

drop table | if exists | tablename;
truncate table tablename;

数值类型

大小(范围)

描述

TINYINT

-128 到 127(有符号)

1 字节整数,用于存储小范围的整数值。

0 到 255(无符号)

SMALLINT

-32,768 到 32,767(有符号)

2 字节整数,用于存储中等范围的整数值。

0 到 65,535(无符号)

MEDIUMINT

-8,388,608 到 8,388,607(有符号)

3 字节整数,用于存储较大范围的整数值。

0 到 16,777,215(无符号)

INT

-2,147,483,648 到 2,147,483,647(有符号)

4 字节整数,用于存储大范围的整数值。

0 到 4,294,967,295(无符号)

BIGINT

-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号)

8 字节整数,用于存储极大范围的整数值。

0 到 18,446,744,073,709,551,615(无符号)

FLOAT

单精度浮点数

4 字节浮点数,用于存储近似数值,精度约为 7 位小数。

DOUBLE

双精度浮点数

8 字节浮点数,用于存储近似数值,精度约为 15 位小数。

DECIMAL(M,D)

精确数值

用于存储精确数值,M 表示总位数,D 表示小数位数。

字符串类型

大小(字符串长度范围)

描述

CHAR(length)

0 - 255 字符

固定长度的字符集。即使插入的字符串小于指定的长度,也会用空格填充到指定的长度。

VARCHAR(length)

0 - 65,535 字符

可变长度的字符集。存储的数据不会超过指定的最大长度,且实际占用的空间更少。

TINYTEXT

0 - 255 字符

最长可存储 255 个字符的字符串。

TEXT

0 - 65,535 字符

最长可存储 65,535 个字符的字符串。

MEDIUMTEXT

0 - 16,777,215 字符

最长可存储 16,777,215 个字符的字符串。

LONGTEXT

0 - 4,294,967,295 字符

最长可存储 4,294,967,295 个字符的字符串。

TINYBLOB

0 - 255 字节

最长可存储 255 字节的二进制数据。

BLOB

0 - 65,535 字节

最长可存储 65,535 字节的二进制数据。

MEDIUMBLOB

0 - 16,777,215 字节

最长可存储 16,777,215 字节的二进制数据。

LONGBLOB

0 - 4,294,967,295 字节

最长可存储 4,294,967,295 字节的二进制数据。

时间类型

大小(范围)

描述

DATE

'1000-01-01' 到 '9999-12-31'

存储日期值,格式为 YYYY-MM-DD

TIME

'-838:59:59' 到 '838:59:59'

存储时间值,格式为 HH:MM:SS

DATETIME

'1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'

存储日期和时间值,格式为 YYYY-MM-DD HH:MM:SS

TIMESTAMP

'1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC

存储日期和时间值,格式为 YYYY-MM-DD HH:MM:SS,与时区相关。

YEAR

1901 到 2155

存储年份值,格式为 YYYYYY(2 位或 4 位)。

DML

1. DML-介绍
DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增删改操作。
- 添加数据(INSERT)
- 修改数据(UPDATE)
- 刪除数据(DELETE)

2. DML

添加数据

1. 给指定字段添加数据
INSERT INTO 表名(字段名1,字段名2,...) VALUES(值1,值2, ...);

2. 给全部字段添加数据
INSERTINTO 表名 VALUES(值1,值2,…);

3. 批量添加数据
INSERT INTO 表名(字段名1,字段名2,⋯)VALUES(值1,值2,),(值1,值2,…),(值1,值2,…);
INSERT INTO 表名 VALUES(值1,值2,…),(值1,值2, ...),(值1,值2,...);

修改数据

UPDATE 表名 SET 字段名1=值1,字段名2=值2,...[WHERE 条件];

update emp set e_name = 'user', gender = '女' where id = 1

删除数据

DELETE FROM 表名 [WHERE 条件]

  • DELETE语句的条件可以有,也可以没有,如果没有条件,则会删除整张表

  • DELETE语句不能删除某一个字段的值(可以使用UPDATE)

DQL

SELECT

字段列表

FROM

表名列表

WHERE

条件列表

GROUP BY

分组字段列表

HAVING

分组后条件列表

ORDER BY

排序字段列表

LIMIT

分页参数

  • 基本查询SELECT 字段1,字段2,字段3, ... FROM 表名

# 去重
select distinct e_name as username from emp;

聚合函数

描述

COUNT()

返回匹配条件的行数。

SUM()

返回数值列的总和。

AVG()

返回数值列的平均值。

MIN()

返回列中的最小值。

MAX()

返回列中的最大值。

GROUP_CONCAT()

将分组中的值连接成一个字符串,可以指定分隔符。

STD()

返回数值列的标准差。

VARIANCE()

返回数值列的方差。

BIT_AND()

对列中的值执行按位与操作。

BIT_OR()

对列中的值执行按位或操作。

BIT_XOR()

对列中的值执行按位异或操作。

  • 分组查询

where与having区别

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

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

DCL

1. 用户管理

CREATE USER‘用户名'@'主机名’IDENTIFIED BY‘密码’;
ALTER USER‘用户名”@'主机名’IDENTIFIED WITH mysqLnative_password BY "密码;
DROP USER‘用户名’@'主机名’

2. 权限控制

GRANT 权限列表 ON 数据库名.表名 TO‘用户名'@'主机名’;
REVOKE 权限列表 ON 数据库名.表名 FROM‘用户名'@主机名”;

2. 函数

# 字符串函数
SELECT CONCAT('Hello', ' ', 'World');  -- 输出: 'Hello World'
SELECT SUBSTRING('Hello World', 7, 5);  -- 输出: 'World'
SELECT REPLACE('Hello World', 'World', 'MySQL');  -- 输出: 'Hello MySQL'
SELECT TRIM('  Hello World  ');  -- 输出: 'Hello World'
SELECT LOWER('Hello World');  -- 输出: 'hello world'
SELECT UPPER('Hello World');  -- 输出: 'HELLO WORLD'
SELECT LPAD('123', 5, '0');  -- 输出: '00123'
SELECT RPAD('123', 5, '0');  -- 输出: '12300'
SELECT REVERSE('Hello');  -- 输出: 'olleH'
SELECT LOCATE('World', 'Hello World');  -- 输出: 7


# 数值函数
SELECT ABS(-10);  -- 输出: 10
SELECT CEIL(3.14);  -- 输出: 4
SELECT FLOOR(3.14);  -- 输出: 3
SELECT ROUND(3.14159, 2);  -- 输出: 3.14
SELECT TRUNCATE(3.14159, 2);  -- 输出: 3.14
SELECT MOD(10, 3);  -- 输出: 1
SELECT POW(2, 3);  -- 输出: 8
SELECT SQRT(16);  -- 输出: 4
SELECT GREATEST(10, 20, 30);  -- 输出: 30
SELECT LEAST(10, 20, 30);     -- 输出: 10
# 日期函数
update emp set e_no = lpad(e_no, '5', '0');
# 生成验证码
select lpad(round(rand()*1000000, 0), 6, '0');

select curdate();
select curtime();
select now();
select year(now());
select month(now());
select day(now());
SELECT DATE('2023-10-05 14:30:00');  -- 输出: 2023-10-05
SELECT YEAR('2023-10-05');  -- 输出: 2023
SELECT DATE_FORMAT('2023-10-05', '%Y年%m月%d日');  -- 输出: 2023年10月05日
SELECT DATE_ADD('2023-10-05', INTERVAL 1 MONTH);  -- 输出: 2023-11-05
SELECT DATEDIFF('2023-10-05', '2023-09-01');  -- 输出: 34
SELECT LAST_DAY('2023-10-05');  -- 输出: 2023-10-31
SELECT STR_TO_DATE('05-10-2023', '%d-%m-%Y');  -- 输出: 2023-10-05
SELECT UNIX_TIMESTAMP('2023-10-05 14:30:00');  -- 输出: 1696512600
SELECT FROM_UNIXTIME(1696512600);  -- 输出: 2023-10-05 14:30:00


# INTERVAL:关键字,表示后面的内容是时间间隔。
select date_add(now(), INTERVAL 90 DAY );

SELECT DATE_ADD('2023-10-05', INTERVAL 1 MONTH);  -- 输出: 2023-11-05
SELECT DATE_SUB('2023-10-05 14:30:00', INTERVAL 2 HOUR);  -- 输出: 2023-10-05 12:30:00
SELECT DATE_ADD('2023-10-05', INTERVAL 1 YEAR);  -- 输出: 2024-10-05
SELECT DATE_SUB('2023-10-05', INTERVAL 3 WEEK);  -- 输出: 2023-09-14

1. 字符串函数

函数名称

描述

CONCAT(str1, str2, ...)

将多个字符串连接成一个字符串。

CONCAT_WS(sep, str1, str2, ...)

用指定的分隔符 sep 连接多个字符串。

SUBSTRING(str, start, length)

从字符串 str 中提取子字符串,从 start 开始,长度为 length

LEFT(str, length)

返回字符串 str 左边的 length 个字符。

RIGHT(str, length)

返回字符串 str 右边的 length 个字符。

LENGTH(str)

返回字符串 str 的字节长度。

CHAR_LENGTH(str)

返回字符串 str 的字符长度。

LOWER(str)

将字符串 str 转换为小写。

UPPER(str)

将字符串 str 转换为大写。

TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)

去除字符串 str 开头或结尾的指定字符 remstr(默认去除空格)。

LTRIM(str)

去除字符串 str 开头的空格。

RTRIM(str)

去除字符串 str 结尾的空格。

REPLACE(str, from_str, to_str)

将字符串 str 中的 from_str 替换为 to_str

REVERSE(str)

反转字符串 str

LOCATE(substr, str)

返回子字符串 substr 在字符串 str 中第一次出现的位置(从 1 开始)。

INSTR(str, substr)

返回子字符串 substr 在字符串 str 中第一次出现的位置(从 1 开始)。

LPAD(str, length, padstr)

padstr 左填充字符串 str,直到长度为 length

RPAD(str, length, padstr)

padstr 右填充字符串 str,直到长度为 length

SPACE(n)

返回由 n 个空格组成的字符串。

REPEAT(str, count)

将字符串 str 重复 count 次。

INSERT(str, pos, len, newstr)

在字符串 strpos 位置插入 newstr,替换 len 个字符。

FORMAT(X, D)

将数字 X 格式化为 D 位小数的字符串。

HEX(str)

返回字符串 str 的十六进制表示。

UNHEX(str)

将十六进制字符串 str 转换为普通字符串。

2. 数值函数

函数名称

描述

ABS(x)

返回 x 的绝对值。

CEIL(x)

返回大于或等于 x 的最小整数(向上取整)。

FLOOR(x)

返回小于或等于 x 的最大整数(向下取整)。

ROUND(x, d)

x 四舍五入到 d 位小数。

TRUNCATE(x, d)

x 截断到 d 位小数(不四舍五入)。

MOD(x, y)

返回 x 除以 y 的余数。

POW(x, y)

返回 xy 次方。

SQRT(x)

返回 x 的平方根。

EXP(x)

返回 ex 次方。

LOG(x)

返回 x 的自然对数(以 e 为底)。

LOG10(x)

返回 x 的以 10 为底的对数。

RAND()

返回一个 0 到 1 之间的随机数。

SIGN(x)

返回 x 的符号:1(正数)、-1(负数)、0(零)。

PI()

返回圆周率 π 的值(约 3.141593)。

SIN(x)

返回 x 的正弦值(x 为弧度)。

COS(x)

返回 x 的余弦值(x 为弧度)。

TAN(x)

返回 x 的正切值(x 为弧度)。

ASIN(x)

返回 x 的反正弦值(结果范围为 -π/2 到 π/2)。

ACOS(x)

返回 x 的反余弦值(结果范围为 0 到 π)。

ATAN(x)

返回 x 的反正切值(结果范围为 -π/2 到 π/2)。

ATAN2(y, x)

返回 y/x 的反正切值(结果范围为 -π 到 π)。

DEGREES(x)

将弧度 x 转换为角度。

RADIANS(x)

将角度 x 转换为弧度。

GREATEST(x1, x2, ...)

返回参数列表中的最大值。

LEAST(x1, x2, ...)

返回参数列表中的最小值。

3. 日期函数

函数名称

描述

NOW()

返回当前日期和时间(格式:YYYY-MM-DD HH:MM:SS)。

CURDATE()

返回当前日期(格式:YYYY-MM-DD)。

CURTIME()

返回当前时间(格式:HH:MM:SS)。

DATE(expr)

提取日期部分(YYYY-MM-DD)。

TIME(expr)

提取时间部分(HH:MM:SS)。

YEAR(date)

返回日期的年份(YYYY)。

MONTH(date)

返回日期的月份(112)。

DAY(date)

返回日期的天数(131)。

HOUR(time)

返回时间的小时数(023)。

MINUTE(time)

返回时间的分钟数(059)。

SECOND(time)

返回时间的秒数(059)。

DAYOFWEEK(date)

返回日期对应的星期几(1=星期日,2=星期一,...,7=星期六)。

WEEK(date)

返回日期所在的年份中的第几周(053)。

DAYOFYEAR(date)

返回日期在年份中的第几天(1366)。

MONTHNAME(date)

返回日期的月份名称(如 January)。

DAYNAME(date)

返回日期的星期名称(如 Monday)。

DATE_FORMAT(date, format)

将日期格式化为指定的字符串格式。

DATE_ADD(date, INTERVAL expr unit)

在日期上添加指定的时间间隔。

DATE_SUB(date, INTERVAL expr unit)

从日期中减去指定的时间间隔。

DATEDIFF(date1, date2)

返回两个日期之间的天数差(date1 - date2)。

TIMESTAMPDIFF(unit, start, end)

返回两个日期之间的差值,单位可以是 YEARMONTHDAY 等。

LAST_DAY(date)

返回日期所在月份的最后一天。

MAKEDATE(year, day)

根据年份和天数返回日期。

MAKETIME(hour, minute, second)

根据小时、分钟和秒返回时间。

STR_TO_DATE(str, format)

将字符串转换为日期。

UNIX_TIMESTAMP([date])

返回日期对应的 UNIX 时间戳(从 1970-01-01 开始的秒数)。

FROM_UNIXTIME(unix_timestamp)

将 UNIX 时间戳转换为日期时间。

4. 流程控制函数

SELECT IF(1 > 0, 'True', 'False');  -- 输出: 'True'
SELECT IFNULL(NULL, 'Default Value');  -- 输出: 'Default Value'
SELECT NULLIF(10, 10);  -- 输出: NULL
SELECT NULLIF(10, 20);  -- 输出: 10

SELECT 
    CASE 
        WHEN score >= 90 THEN 'A'
        WHEN score >= 80 THEN 'B'
        WHEN score >= 70 THEN 'C'
        ELSE 'D'
    END AS grade
FROM students;


SELECT COALESCE(NULL, NULL, 'First Non-NULL Value', 'Second Value');  -- 输出: 'First Non-NULL Value'

函数名称

描述

IF(expr, true_value, false_value)

如果 expr 为真,返回 true_value,否则返回 false_value

IFNULL(expr1, expr2)

如果 expr1 不为 NULL,返回 expr1,否则返回 expr2

NULLIF(expr1, expr2)

如果 expr1 等于 expr2,返回 NULL,否则返回 expr1

CASE

多条件分支控制,类似于编程语言中的 switch-case 语句。

COALESCE(expr1, expr2, ...)

返回参数列表中第一个非 NULL 的值。

3. 约束

# 添加外键
alter table info add constraint dep_foreign_key FOREIGN KEY (status) references dep(id);


# 删除外键
alter table info drop foreign key dep_foreign_key;

约束名称

描述

关键字

主键约束

唯一标识表中的每一行,确保主键列的值唯一且非空。

PRIMARY KEY

外键约束

确保表中的数据与另一张表的数据一致,用于维护表之间的关系。

FOREIGN KEY

唯一约束

确保列中的值唯一,但允许有空值(NULL)。

UNIQUE

非空约束

确保列中的值不能为空(NULL)。

NOT NULL

检查约束

确保列中的值满足指定的条件。

CHECK

默认约束

为列指定默认值,当插入数据时未提供该列的值时使用。

DEFAULT

AUTO_INCREMENT

自动为列生成唯一的递增值,通常用于主键列。

AUTO_INCREMENT

行为关键字

描述

CASCADE

当父表中的记录被删除或更新时,自动删除或更新子表中相关的记录。

SET NULL

当父表中的记录被删除或更新时,将子表中相关记录的外键列设置为 NULL

RESTRICT

阻止删除或更新父表中的记录,如果子表中存在相关记录。

NO ACTION

RESTRICT 相同,阻止删除或更新父表中的记录。

SET DEFAULT

当父表中的记录被删除或更新时,将子表中相关记录的外键列设置为默认值。

详细说明

  1. CASCADE

    • 删除行为:如果父表中的记录被删除,子表中所有相关的记录也会被自动删除。

    • 更新行为:如果父表中的记录的主键被更新,子表中所有相关记录的外键列也会被自动更新。

    • 示例

      CREATE TABLE orders (
          order_id INT PRIMARY KEY,
          user_id INT,
          FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
      );
  2. SET NULL

    • 删除行为:如果父表中的记录被删除,子表中所有相关记录的外键列会被设置为 NULL

    • 更新行为:如果父表中的记录的主键被更新,子表中所有相关记录的外键列会被设置为 NULL

    • 示例

      CREATE TABLE orders (
          order_id INT PRIMARY KEY,
          user_id INT,
          FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL ON UPDATE SET NULL
      );
  3. RESTRICT

    • 删除行为:如果子表中存在相关记录,阻止删除父表中的记录。

    • 更新行为:如果子表中存在相关记录,阻止更新父表中的记录的主键。

    • 示例

      CREATE TABLE orders (
          order_id INT PRIMARY KEY,
          user_id INT,
          FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE RESTRICT ON UPDATE RESTRICT
      );
  4. NO ACTION

    • 删除行为:与 RESTRICT 相同,阻止删除父表中的记录。

    • 更新行为:与 RESTRICT 相同,阻止更新父表中的记录的主键。

    • 示例

      CREATE TABLE orders (
          order_id INT PRIMARY KEY,
          user_id INT,
          FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
      );
  5. SET DEFAULT

    • 删除行为:如果父表中的记录被删除,子表中所有相关记录的外键列会被设置为默认值。

    • 更新行为:如果父表中的记录的主键被更新,子表中所有相关记录的外键列会被设置为默认值。

    • 注意:MySQL 不支持 SET DEFAULT 行为,但某些数据库(如 SQL Server)支持。

    • 示例(假设支持):

      CREATE TABLE orders (
          order_id INT PRIMARY KEY,
          user_id INT DEFAULT 0,
          FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT
      );