SQL 语言全面详解

4 阅读14分钟

SQL 语言全面详解

一、SQL 基础概念

1.1 什么是 SQL

SQL(Structured Query Language,结构化查询语言)是用于管理关系型数据库的标准化编程语言,主要功能包括数据查询、插入、更新、删除及数据库结构定义等。其核心特点:

  • 标准化:遵循 ISO 制定的 SQL99 等标准,跨数据库通用(如 MySQL、Oracle、SQL Server)。
  • 操作对象:针对数据库、表、记录等进行操作,实现对数据的 CRUD(Create、Read、Update、Delete)。

1.2 SQL 与数据库的关系

  • MySQL 是数据库管理软件(RDBMS),而 SQL 是操作 MySQL 的语言。

数据库对象层级关系:

数据库软件(如 MySQL)→ 数据库(Database)→ 数据表(Table)→ 列(Column/字段)→ 行(Row/记录)  

1.3 SQL 语言分类

按功能分为四大类:

分类全称作用核心操作
DDL数据定义语言定义 / 修改数据库、表等结构CREATEALTERDROP
DML数据操作语言操作表中数据(增删改)INSERTUPDATEDELETE
DQL数据查询语言查询表中数据SELECT
DCL数据控制语言管理用户权限和安全GRANTREVOKE

二、DDL(数据定义语言)

用于定义数据库、表、列等结构,不直接操作数据。

2.1 数据库操作

操作语法示例说明
查看所有数据库SHOW DATABASES;显示 MySQL 中所有数据库(含系统库)
创建数据库CREATE DATABASE 库名;``CREATE DATABASE IF NOT EXISTS 库名;若库不存在则创建(避免重复报错)
删除数据库DROP DATABASE 库名;``DROP DATABASE IF EXISTS 库名;若库存在则删除(谨慎操作,不可恢复)
切换数据库USE 库名;指定当前操作的数据库(必须先执行)
查看当前数据库SELECT DATABASE();显示当前正在操作的数据库

2.2 数据表操作

2.2.1 表的创建与查看
操作语法示例说明
查看当前库所有表SHOW TABLES;需先执行 USE 库名;
创建表sql CREATE TABLE 表名( 列名1 数据类型 [约束], 列名2 数据类型 [约束], ... -- 最后一列无逗号 );定义表的字段、类型及约束
查看表结构DESC 表名; 或 SHOW COLUMNS FROM 表名;显示表的字段名、类型、约束等信息
2.2.2 表的修改与删除
操作语法示例说明
修改表名ALTER TABLE 旧表名 RENAME TO 新表名;重命名数据表
新增列ALTER TABLE 表名 ADD 列名 数据类型 [约束];``ALTER TABLE 表名 ADD 列名 类型 AFTER 已有列;在指定位置添加新字段
删除列ALTER TABLE 表名 DROP 列名;从表中删除指定字段(数据会丢失)
修改列名 / 类型ALTER TABLE 表名 CHANGE 旧列名 新列名 新类型 [约束];同时修改列名和类型
修改列类型ALTER TABLE 表名 MODIFY 列名 新类型 [约束];仅修改列的类型或约束
删除表DROP TABLE 表名;``DROP TABLE IF EXISTS 表名;若表存在则删除(数据和结构全丢失)

DDL示例

数据库创建→切换→表创建→表结构查看→表名修改→增列→改列类型→改列名→删列→删表→删库

-- 一、数据库操作
-- 查看所有数据库
SHOW DATABASES;
-- 创建数据库(不存在则创建)
CREATE DATABASE IF NOT EXISTS mydb;
-- 删除数据库(存在则删除)
DROP DATABASE IF EXISTS mydb;
 
-- 切换数据库
USE mydb;
-- 查看当前数据库
SELECT DATABASE();
 
-- 二、数据表操作(需先执行 USE mydb;)
-- 2.1 表的创建与查看
-- 创建表(用户表:id主键、姓名、年龄)
CREATE TABLE user (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  age INT
);
 
-- 查看当前库所有表
SHOW TABLES;
-- 查看表结构
DESC user;
SHOW COLUMNS FROM user;
 
-- 2.2 表的修改与删除
-- 修改表名(user→t_user)
ALTER TABLE user RENAME TO t_user;
 
-- 新增列(添加性别列,在name后)
ALTER TABLE t_user ADD gender CHAR(1) AFTER name;
-- 删除列(删除age列)
ALTER TABLE t_user DROP age;
-- 修改列名+类型(name→username,长度30)
ALTER TABLE t_user CHANGE name username VARCHAR(30);
-- 仅修改列类型(gender改为VARCHAR(2))
ALTER TABLE t_user MODIFY gender VARCHAR(2);
 
-- 删除表(存在则删除)
DROP TABLE IF EXISTS t_user;
AI写代码sql

三、数据类型与约束

3.1 常用数据类型

类型分类具体类型说明及示例
数值型INT整数(默认长度 11,如 id INT
DOUBLE(M,D)浮点型(M 总长度,D 小数位,如 score DOUBLE(5,2)
字符串型CHAR(N)定长字符串(不足补空格,如 sex CHAR(1)
VARCHAR(N)可变长字符串(按实际长度存储,如 name VARCHAR(20)
日期时间型DATE日期(年 - 月 - 日,如 birthday DATE
DATETIME日期 + 时间(年 - 月 - 日 时:分: 秒,如 create_time DATETIME

3.2 约束(Constraint)

约束用于限制表中数据,保证数据完整性和一致性。

约束类型关键字作用示例
主键约束PRIMARY KEY列值非空且唯一(唯一标识记录)id INT PRIMARY KEY
自增约束AUTO_INCREMENT配合主键使用,自动递增(避免重复)id INT PRIMARY KEY AUTO_INCREMENT
唯一约束UNIQUE列值可空但不可重复(如手机号)phone VARCHAR(20) UNIQUE
非空约束NOT NULL列值不可为空(如姓名)name VARCHAR(20) NOT NULL
默认值约束DEFAULT未赋值时使用默认值(如性别默认 “男”)sex CHAR(1) DEFAULT '男'
外键约束FOREIGN KEY关联多表(子表值需存在于父表主键中)sql FOREIGN KEY(uid) REFERENCES user(id)

四、DML(数据操作语言)

用于操作表中的数据(增、删、改)。

4.1 插入数据(INSERT

-- 插入指定列(列与值需一一对应)  
INSERT INTO 表名(列1, 列2, ...) VALUES(值1, 值2, ...);  

-- 插入所有列(按表结构顺序,不推荐)  
INSERT INTO 表名 VALUES(值1, 值2, ...);  

-- 批量插入(效率更高)  
INSERT INTO 表名(列1, 列2) VALUES(值1, 值2), (值1, 值2), ...;  

示例

-- 插入一条学生记录  
INSERT INTO stu(sid, sname, age) VALUES(1001, '张三', 18);  
 
-- 批量插入  
INSERT INTO stu(sname, score) VALUES('李四', 90), ('王五', 85);  
AI写代码sql

4.2 更新数据(UPDATE

语法

-- 必须加 WHERE 条件,否则更新全表!  
UPDATE 表名 SET 列1=值1, 列2=值2, ... WHERE 条件;  

示例

-- 更新 id=1001 的学生年龄为 20  
UPDATE stu SET age=20 WHERE sid=1001;  
 
-- 批量更新(成绩+5,条件:班级=3)  
UPDATE stu SET score=score+5 WHERE cid=3;  
AI写代码sql

4.3 删除数据(DELETE

语法

-- 必须加 WHERE 条件,否则删除全表数据!  
DELETE FROM 表名 WHERE 条件;  

示例

-- 删除 id=1002 的学生  
DELETE FROM stu WHERE sid=1002;  
 
-- 删除年龄 < 18 的学生  
DELETE FROM stu WHERE age < 18;  
AI写代码sql

4.4 DELETE 与 TRUNCATE 区别

特性DELETE(DML)TRUNCATE(DDL)
原理逐条删除记录(日志可恢复)删除表结构后重建(不可恢复)
自增影响不重置自增序列(继续递增)重置自增序列(从 1 开始)
效率慢(逐行删除)快(直接重建表)

五、DQL(数据查询语言)

用于查询表中数据,返回虚拟结果集(不修改原表),是 SQL 中最核心的部分。

5.1 基本查询

语法

-- 查询指定列  
SELECT1, 列2, ... FROM 表名;  
 
-- 查询所有列(不推荐,效率低)  
SELECT * FROM 表名;  
 
-- 列取别名(AS 可省略)  
SELECT1 AS 别名1, 列2 别名2 FROM 表名;  
AI写代码sql

示例

-- 查询学生的学号、姓名、成绩  
SELECT sid, sname, score FROM stu;  
 
-- 别名查询(显示“姓名”“成绩”)  
SELECT sname 姓名, score 成绩 FROM stu;  
AI写代码

5.2 条件查询(WHERE

条件查询就是在基础查询基础上,再给sql设置条件,只查询部分符合条件的数据

条件语句 : select 字段1,字段2,... from 表名 where 字段 条件 值;

语法

SELECT 列名 FROM 表名 WHERE 条件;  

AI写代码sql

常用条件运算符

类型运算符 / 关键字说明
比较=!=><>=<=等于、不等于、大于、小于等
逻辑ANDORNOT且、或、非
范围BETWEEN 值1 AND 值2在值 1 到值 2 之间(包含边界)
集合IN(值1, 值2, ...)NOT IN(...)在 / 不在指定集合中
空值IS NULLIS NOT NULL判断是否为空(不能用 = 或 !=

示例

-- ============== 条件查询 ==============
-- 查询学号为1001的学生信息
select * from stu where sid = 1001;
-- 查询学生成绩大于60的学生id 姓名,成绩
select sid,sname,score from stu where score > 60;
-- 查询学生性别为女,并且年龄小于50的记录
select * from stu where sex = '女' and  age < 50;
-- 查询学生学号为1001,或者姓名为李四的记录
select * from stu where sid = 1001 or sname = '李四';
-- 查询学号为1001,1002,1003的记录
select * from stu where sid = 1001 or sid = 1002 or sid = 1003;
select * from stu where sid in (1001,1002,1003);
select * from stu where sid >= 1001 and sid <= 1003;
-- 查询学号不是1001,1002,1003的记录
select * from stu where sid not in (1001,1002,1003);
select * from stu where sid != 1001 and sid != 1002 and sid != 1003;
-- 查询学生年龄在20到40之间的学生记录
select * from stu where age >= 20 and age <= 40;
select * from stu where age between 20 and 40;
-- 查询性别非男的学生记录
select * from stu where sex != '男';
select * from stu where sex = '女';
--  查询性别为null的学生记录
update stu set sex = null where sid = 1001.;
--  查询是不能=null运算
-- select * from stu where sex = null;
select * from stu where sex is null;
--  查询性别不为null的学生记录
select * from stu where sex is not null;
AI写代码sql

5.3 模糊查询(LIKE

模糊查询其实也是条件查询

用于匹配字符串的部分内容,配合通配符使用:

  • %:匹配任意多个字符(包括 0 个);
  • _:匹配单个字符(开发中少用)。

示例

-- 姓名以“张”开头  
SELECT * FROM stu WHERE sname LIKE '张%';  
 
-- 姓名中包含“三”  
SELECT * FROM stu WHERE sname LIKE '%三%';  
AI写代码sql

5.4 排序查询(ORDER BY

对查询后的数据按照指定字段以及指定规则排序

  • desc 降序
  • asc 升序,默认是升序

排序查询写在最后

语法

SELECT 列名 FROM 表名 [WHERE 条件] ORDER BY 列名 [ASC|DESC];  
-- ASC:升序(默认);DESC:降序  
-- 多列排序:先按列1排序,列1相同则按列2排序  
AI写代码sql

示例

-- 按年龄降序  
SELECT * FROM stu ORDER BY age DESC;  
 
-- 成绩升序,同成绩按年龄降序  
SELECT * FROM stu WHERE score > 60 ORDER BY score ASC, age DESC;  
AI写代码sql

5.5 聚合函数

对一列数据计算并返回单一结果(忽略 NULL 值):

  • 聚合运算完,结果只有一行数据
  • 其他字段不能和聚合函数同时查询 ?,除非有分组查询
函数说明示例
COUNT(列名)统计该列非空行数SELECT COUNT(id) FROM stu;
COUNT(*)统计所有行数(含 NULLSELECT COUNT(*) FROM stu;
SUM(列名)求和SELECT SUM(score) FROM stu;
AVG(列名)求平均值SELECT AVG(age) FROM stu;
MAX(列名)求最大值SELECT MAX(score) FROM stu;
MIN(列名)求最小值SELECT MIN(age) FROM stu WHERE sex='男';

5.6 分组查询(GROUP BY

分组查询,就是按指定列分组,对每组数据进行聚合运算。

  • group by 字段,根据指定字段分组
  • having 字段 值, 分组后再过滤

有个非常重要特点: SQL只要有分组,分成几组,查询结果就只有几行,所以一般配合聚合函数来使用,是组内数据的聚合

--------------------------------------------------------------------------------

分组查询的特点:

  1. group by语句中,select后的字段必须出现group by中
    或者说

        与聚合函数同时出现的列,必须出现在group by中
否则会报错
2) 分成几组,最终结果是几行记录
3) 聚合函数是对分组后组内聚合的

having和where都是过滤数据,什么区别?

  • where是分组前过滤,having是分组后过滤
  • where后不能使用聚合函数,having可以聚合函数

ff

语法

SELECT 分组列, 聚合函数(列) FROM 表名  
[WHERE 分组前条件]   -- 先过滤再分组  
GROUP BY 分组列  
[HAVING 分组后条件]; -- 分组后过滤(可使用聚合函数)  
AI写代码sql

核心规则SELECT 后只能出现 分组列 或 聚合函数

示例

-- 按班级分组,统计每班人数和平均成绩  
SELECT cid, COUNT(sid) 人数, AVG(score) 平均分 FROM stu GROUP BY cid;  
 
-- 筛选平均分 > 80 的班级(分组后过滤)  
SELECT cid, AVG(score) 平均分 FROM stu  
GROUP BY cid  
HAVING 平均分 > 80;  
AI写代码sql

5.7 分页查询(LIMIT

限制查询结果的行数,常用于分页展示。

就是将查询完的数据,可以限制展现条数

语法: limit n -- 限制输出指定n条,从第一条开始

         limit x,y -- 限制输出,从x下标处输出y条,第一条的下标是0

语法

SELECT 列名 FROM 表名 [WHERE 条件] LIMIT 起始索引, 每页条数;  
-- 起始索引 = (页码 - 1) * 每页条数(从 0 开始)  
AI写代码sql

示例

-- 第 1 页(3 条/页)  
SELECT * FROM stu LIMIT 0, 3;  
 
-- 第 2 页(3 条/页)  
SELECT * FROM stu LIMIT 3, 3;  
AI写代码sql

5.8 去重查询(DISTINCT

去除查询结果中指定列的重复值(通常配合聚合函数使用)。

示例

-- 统计不同年龄的人数  
SELECT COUNT(DISTINCT age) 不同年龄人数 FROM stu;  
AI写代码sql

六、多表查询

当数据分布在多个表中时,需通过关联查询获取完整信息。

6.1 表关系类型

  • 一对一:如 “用户” 与 “身份证”(一个用户对应一个身份证)。
  • 一对多:如 “班级” 与 “学生”(一个班级包含多个学生)。
  • 多对多:如 “订单” 与 “商品”(一个订单可含多个商品,一个商品可在多个订单中)。

6.2 内连接(INNER JOIN

只查询两表中匹配关联条件的记录。

语法

SELECT 字段列表 FROM1  
INNER JOIN2  
ON1.关联列 =2.关联列;  
AI写代码sql

示例

-- 查询学生信息及所属班级名称(stu 表 cid 关联 class 表 cid)  
SELECT s.sid, s.sname, c.cname  
FROM stu s  
INNER JOIN class c  
ON s.cid = c.cid;  
AI写代码sql

6.3 外连接

外连接又分为左外连接,右外连接 :

  • 左外连接(LEFT JOIN :保留左表所有记录,右表不匹配则为 NULL
  • 右外连接(RIGHT JOIN :保留右表所有记录,左表不匹配则为 NULL

示例

-- 左外连接:查询所有学生(含无班级的学生)及班级名称  
SELECT s.sname, c.cname  
FROM stu s  
LEFT JOIN class c  
ON s.cid = c.cid;  
 
-- 右外连接:查询所有班级(含无学生的班级)及学生姓名  
SELECT c.cname, s.sname  
FROM stu s  
RIGHT JOIN class c  
ON s.cid = c.cid;  
AI写代码sql

6.4 子查询(嵌套查询)

将一个查询结果作为另一个查询的条件或表。

子查询(subquery)也叫嵌套查询

  • 1.将sql语句查询的结果当成一张表,写在from后面 必须起别名的,不起报错!
  • 2.将sql语句当条件,写在where后面
(1)子查询作为条件
-- 单行子查询:查询年龄大于“张三”的学生  
SELECT * FROM stu  
WHERE age > (SELECT age FROM stu WHERE sname = '张三');  
 
-- 多行子查询:查询与“张三”同班级的学生  
SELECT * FROM stu  
WHERE cid IN (SELECT cid FROM stu WHERE sname = '张三');  
AI写代码sql
(2)子查询作为表(需起别名)
-- 查询男生中年龄 > 20 的用户  
SELECT * FROM (  
  SELECT * FROM stu WHERE sex = '男'  -- 子查询结果作为临时表  
) AS temp  
WHERE temp.age > 20;  
AI写代码sql

七、SQL 执行与书写顺序

7.1 书写顺序(推荐)

SELECT 列名  
FROM 表名  
WHERE 条件  
GROUP BY 分组列  
HAVING 分组后条件  
ORDER BY 排序列  
LIMIT 起始索引, 条数;  
AI写代码sql

7.2 执行顺序(核心)

  1. FROM:获取表的所有数据;
  2. WHERE:过滤不符合条件的行;
  3. GROUP BY:按指定列分组;
  4. HAVING:过滤不符合条件的组;
  5. SELECT:提取指定列(含聚合运算);
  6. ORDER BY:对结果排序;
  7. LIMIT:限制返回行数。

八、DCL(数据控制语言)

用于管理用户权限和数据库安全(较少直接使用,多通过工具配置)。

操作语法示例说明
创建用户CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';主机名 % 表示允许远程连接
授权GRANT 权限 ON 库名.表名 TO '用户名'@'主机名';如 GRANT SELECT ON mydb.stu TO 'test'@'%';
撤销权限REVOKE 权限 ON 库名.表名 FROM '用户名'@'主机名';收回指定权限

总结

SQL 是操作关系型数据库的核心语言,需重点掌握:

  • DDL:定义数据库和表结构(CREATEALTERDROP);
  • DML:操作数据(INSERTUPDATEDELETE);
  • DQL:查询数据(条件、排序、聚合、分组、多表连接、子查询);
  • 约束:保证数据完整性(主键、非空、外键等)。