SQL语法讲解
一、语法分类
1.1、SQL通用语法
- SQL语句可以单行或多行书写,以分号(;)结尾。
- SQL语句可以使用空格/缩进来增强语句的可读性。
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
- 注释:
- 单行注释:--注释内容或#注释内容(MySQL我有)
- 多行注释:/*注释内容*/
1.2、SQL分类
- DDL:数据定义语言,用来定义数据库对象(数据库,表,字段)。
- DML:数据操作语言,用来对数据库表中的数据进行增删改。
- DQL:数据查询语言,用来查询数据库中表的记录。
- DCL:数据控制语言,用来创建数据库用户、控制数据库的访问权限。
二、DDL语句讲解
2.1、DDL数据库操作
- 查询
查询所有数据库
SHOW DATABASES; |
查询当前数据库
SELECT DATABASE(); |
检索用于当前 MySQL 连接的当前数据库的名称。执行此查询时,它将返回当前所选数据库的名称。
创建
CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARACTER SET 字符集] [COLLATE 排序规则]; |
- IF NOT EXISTS:这是一个可选子句,用于防止在具有指定名称的数据库已存在时发生错误。如果数据库存在,则该语句无效。
- 数据库名:这是要为新数据库提供的名称。
- DEFAULT CHARACTER SET 字符集:这是一个可选子句,用于指定新数据库的默认字符集。字符集根据字符编码确定数据的存储和处理方式。
- COLLATE 排序规则:这是一个可选子句,用于指定新数据库的默认排序规则。排序规则定义用于比较字符集中字符的规则。
示例:
CREATE DATABASE IF NOT EXISTS test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; |
此示例创建一个名为“test”的数据库,其默认字符集为 UTF-8,排序规则为“utf8_general_ci”。您可以根据需要修改数据库名称、字符集和排序规则。
删除:
DROP DATABASE [IF EXISTS] 数据库名; |
此语句删除名为“xx”的数据库(如果存在)。如果数据库不存在,则该语句无效。
使用:
USE 数据库名; |
2.2、DDL表操作数据类型
案例:根据需求创建表(设计合理的数据类型、长度)
设计一第员工信息表,要求如下:
编号(纯数字)、员工工号(字符串类型,长度不超过10位)、员工姓名(字符串类型,长度不超过10位)、性别(男/女,存储一个汉字)、年龄(正常人年龄,不可能存储负数)、身份证号(二代身份证号均为18位,身份证号有X这样的字符)、入职时间(取值年月日即可)。
语法:
CREATE TABLE EMP ( ID INT COMMENT '编号', WorkNO VARCHAR(10) COMMENT '工号', Name VARCHAR(10) COMMENT '姓名', Gender CHAR(1) CHECK(Gender IN ('男', '女')) COMMENT '性别', Age TINYINT UNSIGNED COMMENT '年龄' CHECK (Age >= 0), IDCard CHAR(18) COMMENT '身份证号', EntryDate DATE COMMENT '入职时间' ) COMMENT '员工表'; |
查看表的结构:
DESCRIBE EMP; |
2.3、DDL表操作修改
- 添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT注释] [约束]; |
案例:为EMP表增加一个新的字段“昵称”为nickname,类型为varchar(20)。
- 修改数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度); |
ALTER TABLE语句用于修改表的结构,包括添加、删除或修改列的数据类型。MODIFY关键字用于修改列的定义。
案例:将 Gender 列的数据类型修改为 CHAR(4)
ALTER TABLE employee MODIFY Gender CHAR(4); |
- 修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束]; |
案例:将EMP表的nickname字段修改为username,类型为varchar(30)
ALTER TABLE EMP CHANGE nickname username varchar(30) COMMENT ‘昵称’; |
- 删除字段
ALTER TABLE 表名 DROP 字段名; |
案例:将EMP表的字段username删除
- 修改表名
ALTER TABLE 表名 RENAME TO新表名; |
案例:将EMP表的表名修改为employee
ALTER TABLE EMP RENAME TO employee; |
- 删除表
DROP TABLE [IF EXISTS] 表名; |
删除指定表,并重新创建该表
TRUNCATE TABLE 表名; |
用于删除表中的所有数据,但保留表的结构(列、索引等);TRUNCATE TABLE是一个DDL(数据定义语言)语句,而不是DML(数据操作语言)语句,因此它在事务中不能回滚。使用TRUNCATE TABLE将删除表中的所有行,而不是使用DELETE语句逐行删除,因此通常比DELETE语句更快。
三、DML语句讲解
3.1、DML介绍
DML(数据操作语言)用来对数据库中表的数据记录进行增删改操作。
- 添加数据(INSERT)
- 修改数据(UPDATE)
- 删除数据(DELETE)
3.2、DML添加数据
- 给指定字段添加数据
INSERT INTO 表名(字段1,字段2,...) VALUES(值1,值2,...); |
- INSERT INTO:这是指示要将数据插入表中的关键字。
- 表名:将其替换为要插入数据的表的实际名称。
- (字段1, 字段2, ...):这些是要向其插入数据的表中的列的名称。列出括号内的列。
- VALUES:此关键字后跟一组括在括号中的值。这些值对应于前面列出的列。
- (值1, 值2, ...):这些是要插入到相应列中的实际值。这些值的顺序应与列的顺序相同。
示例:在“Employees”表中插入一条新记录,其中包含“ID”、“Name”和“LastName”的指定值
INSERT INTO employee(ID,WorkNO,Name,Gender,Age,IDCard,EntryDate) VALUES(‘1’,’1’,’ITcast’,’男’,’18’,’123456789012345678’,’2023-10-07’) |
给全部字段添加数据
INSERT INTO 表名 VALUES(值1,值2,...); |
批量添加数据
INSERT INTO 表名(字段1,字段2,...) VALUES(值1,值2,...), (值1,值2,...), (值1,值2,...); |
INSERT INTO 表名 VALUES(值1,值2,...), (值1,值2,...), (值1,值2,...); |
- 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
- 字符串和日期型数据应该包含在引号中。
- 插入的数据大小,应该在字段的规定范围内。
3.3、DML修改数据
UPDATE 表名 SET 字段名1=值1,字段名2=值2,... [WHERE 条件]; |
示例:修改employee表的ID为1、字段Name为ITcast的值改成“MengHao”,Age改为20。
UPDATE employee SET Name=‘MengHao’,Age=’20’ WHERE ID =1; |
注意:修改语句的条件可以没有,如果不指定WHERE条件,使用新值会更新指定表中的所有记录。
3.4、DML删除数据
DELETE FROM 表名 [WHERE 条件]; |
示例:删除ID为4的那行数据。
DELETE FROM employee WHERE ID =4; |
注意:DELETE语句不能删除某个字段的值(可以使用UPDATE)。
四、DQL语句讲解
4.1、DQL介绍
DQL(数据查询语言)用来查询数据库中表的记录。
查询关键字:SELECT
DQL语法:
SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 LIMIT 分页参数 |
- 基本查询
- 条件查询(WHERE)
- 聚合函数(count、max、min、avg、sum)
- 分组查询(GROUP BY)
- 排序查询(ORDER BY)
- 分布查询(LIMIT)
4.2、DQL基本查询
- 查询多个字段
SELECT 字段1,字段2,字段3... FROM 表名; |
SELECT * FROM 表名; |
示例:查询指定字段Name,WorkNO,Age并返回
SELECT Name,WorkNO,Age FROM employee; |
设置别名
SELECT 字段1 [AS 别名1],字段2 [AS 别名2]... FROM 表名; |
设置别名时,AS可以省略。
示例:查询所有员工的入职日期,并起别名
SELECT EntryDate AS ‘入职日期’ FROM employee; |
去除重复记录
SELECT DISTINCT 字段列表 FROM 表名; |
示例:查询表内员工的年龄(不要重复)
SELECT DISTINCT Age FROM employee; |
此查询将从指定表中的“AGE”列返回唯一值,从而消除任何重复值。
4.3、DQL条件查询
- 语法
SELECT 字段列表 FROM 表名 WHERE 条件列表; |
- 条件
比较运算符 | 功能 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
<>或!= | 不等于 |
BETWEEN...AND... | 在某个范围之内(含最小、最大值) |
IN(...) | 在in之后的列表中的值,多选一 |
LIKE 占位符 | 模糊匹配(匹配单个字符,%匹配任意个字符) |
IS NULL | 是NULL |
AND 或 && | 并且(多个条件同时成立) |
OR 或 || | 或者(多个条件任意一个成立) |
NOT 或 ! | 非,不是 |
- 案例
- 查询年龄小于等于20的员工
SELECT * FROM employee WHERE Age <= 20; |
查询有身份证号的员工信息
SELECT * FROM employee WHERE IDCard IS NOT NULL; |
查询年龄在15(包含)到21(包含)之间的员工信息
SELECT * FROM employee WHERE Age >= 15 AND Age <= 21; |
SELECT * FROM employee WHERE Age >= 15 && Age <= 21; |
SELECT * FROM employee WHERE Age BETWEEN 15 AND 21; |
查询年龄等于20或18或21的员工信息
SELECT * FROM employee WHERE Age IN(20,18,21); |
查询名字为M开头的员工信息
SELECT * FROM employee WHERE Name LIKE ‘M%’; |
查询身份证号第一位是3的员工信息
SELECT * FROM employee WHERE IDCard LIKE ‘3%’; |
4.4、DQL聚合函数
将一列数据作为一个整体,进行纵向计算。
常见聚合函数:
函数 | 功能 | 函数 | 功能 |
count | 统计数量 | avg | 平均值 |
max | 最大值 | sum | 求和 |
min | 最小值 |
语法:
SELECT 聚合函数(字段列表) FROM 表名; |
- 示例:统计该企业员工数量
SELECT count(*) FROM employee; |
SELECT count(IDCard) FROM employee; |
示例:统计该企业员工的平均年龄
SELECT avg(Age) FROM employee; |
4.5、DQL分组查询
语法:
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件]; |
- where与having区别
- 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
- 判断条件不同:where不能对聚合函数进行判断,而having可以。
- 示例:根据性别分组,统计男性员工和女性员工的数量
SELECT COUNT(*) FROM employee GROUP BY Gender; |
- 示例:查询年龄小于21的员工,并根据员工性别分组,获取员工地区数量大于等于2的
SELECT Region,count(*) FROM employee WHERE Age < 21 GROUP BY Region HAVING COUNT(*)>=2; |
SELECT Region,count(*) C FROM employee WHERE Age <21 GROUP BY Region HAVING C>=2; |
注意:执行顺序:where > 聚合函数 > having;分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
4.6、DQL排序查询
- 语法
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1,字段2 排序方式2; |
支持多字段排序。
- 排序方式
- ASC:升序(默认值)
- DESC:降序
- 案例
- 根据年龄对公司的员工进行降序排序
SELECT * FROM employee order by Age DESC; |
根据年龄对公司的员工进行降序排序,年龄相同,再按照入职时间进行升序排序
SELECT * FROM employee ORDER BY Age DESC,EntryDate AS; |
注意:如果是多字段排序,当一个字段值相同时,才会根据第二个字段进行排序。
4.7、DQL分页查询
- 语法
SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数; |
注意:
- 起始索引从0开始,起始索引=(查询页码-1)*每页显示记录数。
- 分布查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。
- 如果查询的的是第一页数据,起始索引可以省略,直接简写为limit 10.
- 案例
- 示例:查询第1页员工数据,每页显示10条记录
SELECT * FROM employee limit 0,10; |
SELECT * FROM employee limit 10; |
- 示例:查询第2页员工数据,每页展示10条记录 ----à(页码-1)*页展示记录数
SELECT * FROM employee LIMIT 10,10; |
计算方法:(2-1) * 10
4.8、执行顺序
五、DCL语句讲解
DCL(数据控制语言)用来管理数据库用户、控制数据库的访问权限。
5.1、DCL管理用户
- 查询用户
USE mysql; SELECT user, host FROM mysql.user; |
创建用户
CREATE USER ‘用户名’@’主机名’ IDENTIFIED BY ‘密码’; |
修改密码
ALTER USER ‘用户名’@’主机名’ IDENTIFIED WITH mysql_native_password BY ‘新密码’; |
'authentication_plugin' 是要使用的身份验证插件,例如 mysql_native_password。'mysql_native_password' 是 MySQL 的一种常见的身份验证插件。
- 删除用户
DROP USER ‘用户名’@’主机名’; |
5.2、DCL权限控制
查询权限
SHOW GRANTS FOR ‘用户名’@’主机名’; |
返回授予该用户在指定主机上的权限的 SQL 语句。
- 授予权限
GRANT 权限列表 ON 数据库名.表名 TO ‘用户名‘@’主机名‘; |
- 示例:授予用户在 MyDB 数据库上执行所有权限
GRANT ALL PRIVILEGES ON MyDB.* TO 'username'@'hostname'; |
- 示例:授予用户在 MyDB 数据库的 employee 表上执行 SELECT 和 INSERT 的权限
GRANT SELECT, INSERT ON MyDB.employee TO 'username'@'hostname'; |
- 示例:授予用户在所有数据库上执行所有权限
GRANT ALL PRIVILEGES ON *.* TO 'username'@'hostname'; |
- 撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM ‘用户名‘@’主机名‘; |
- 权限列表 是你要撤销的权限,可以是 SELECT、INSERT、UPDATE、DELETE 等,也可以使用 ALL PRIVILEGES 撤销所有权限。
- 数据库名.表名 指定了你要从用户撤销权限的数据库和表。如果你希望在整个数据库上撤销权限,可以只指定数据库名。
- '用户名'@'主机名' 指定了接收权限的用户以及允许连接的主机。如果你希望从任何主机都撤销权限,可以使用 '%' 作为通配符。
注意:多个权限之间,使用逗号分隔;授权时,数据库名和和表名可以使用*进行通配,代表所有。