SQL常用语法全解析:从入门到进阶的实战指南

SQL(Structured Query Language,结构化查询语言)是操作关系型数据库的核心工具,无论是后端开发、数据分析、运维监控,还是大数据处理,SQL都是不可或缺的技能。从简单的"查询数据"到复杂的"多表关联分析",SQL的语法体系既基础又灵活。

本文将从**基础语法、进阶语法、常用函数、性能优化小贴士**四个维度,结合实战案例详细讲解常见SQL语法,覆盖MySQL、Oracle、SQL Server等主流数据库的通用用法,帮你快速掌握SQL的核心应用。

一、先搭个基础:示例表结构

为了让语法示例更易理解,我们先定义三个常用的示例表(后续案例均基于这三张表):

1. 学生表(student)

|--------------|-------------|----------|
| 字段名 | 类型 | 说明 |
| student_id | INT | 学生ID(主键) |
| student_name | VARCHAR(50) | 学生姓名 |
| age | INT | 年龄 |
| gender | VARCHAR(10) | 性别 |
| class_id | INT | 班级ID(外键) |

2. 班级表(class)

|------------|-------------|----------|
| 字段名 | 类型 | 说明 |
| class_id | INT | 班级ID(主键) |
| class_name | VARCHAR(50) | 班级名称 |
| teacher | VARCHAR(50) | 班主任 |

3. 成绩表(score)

|-------------|--------------|----------|
| 字段名 | 类型 | 说明 |
| score_id | INT | 成绩ID(主键) |
| student_id | INT | 学生ID(外键) |
| course_name | VARCHAR(50) | 课程名称 |
| score | DECIMAL(5,2) | 分数 |

二、SQL基础语法:数据库与表的核心操作

SQL基础语法主要分为**DDL(数据定义语言)******和******DML(数据操作语言)**,前者负责定义数据库/表结构,后者负责操作数据。

1. DDL:数据库与表的定义(创建/修改/删除)

(1)数据库操作
复制代码
sql 复制代码
-- 1. 创建数据库(指定字符集,避免中文乱码)
CREATE DATABASE IF NOT EXISTS school_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 2. 使用数据库
USE school_db;

-- 3. 删除数据库(谨慎使用!)
DROP DATABASE IF EXISTS school_db;
(2)表操作
sql 复制代码
-- 1. 创建学生表(含主键、数据类型、注释)
CREATE TABLE IF NOT EXISTS student (
    student_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',
    student_name VARCHAR(50) NOT NULL COMMENT '学生姓名',
    age INT COMMENT '年龄',
    gender VARCHAR(10) COMMENT '性别',
    class_id INT COMMENT '班级ID',
    -- 外键关联班级表(可选,视业务场景而定)
    FOREIGN KEY (class_id) REFERENCES class(class_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生表';

-- 2. 修改表结构(添加字段、修改字段、删除字段)
-- 添加字段:新增手机号字段
ALTER TABLE student ADD COLUMN phone VARCHAR(20) COMMENT '手机号' AFTER age;
-- 修改字段:修改age字段类型为TINYINT
ALTER TABLE student MODIFY COLUMN age TINYINT COMMENT '年龄';
-- 删除字段:删除手机号字段
ALTER TABLE student DROP COLUMN phone;

-- 3. 删除表(谨慎使用!)
DROP TABLE IF EXISTS student;

-- 4. 清空表数据(保留表结构,自增主键重置)
TRUNCATE TABLE student;

2. DML:数据的增删改查(核心中的核心)

(1)插入数据(INSERT)
sql 复制代码
-- 1. 插入单条数据(指定字段)
INSERT INTO student (student_name, age, gender, class_id)
VALUES ('张三', 18, '男', 1);

-- 2. 插入多条数据(批量插入,效率更高)
INSERT INTO student (student_name, age, gender, class_id)
VALUES 
('李四', 19, '男', 1),
('王五', 18, '女', 2),
('赵六', 20, '男', 2);

-- 3. 从其他表插入数据(将查询结果插入表中)
INSERT INTO student_backup (student_id, student_name, age)
SELECT student_id, student_name, age FROM student WHERE gender = '女';
(2)查询数据(SELECT)

SELECT是SQL中使用最频繁的语法,基础用法如下:

sql 复制代码
-- 1. 查询所有字段(不推荐,性能差,仅测试用)
SELECT * FROM student;

-- 2. 查询指定字段
SELECT student_id, student_name, age FROM student;

-- 3. 带条件查询(WHERE子句)
SELECT student_name, age FROM student WHERE gender = '男' AND age > 18;

-- 4. 去重查询(DISTINCT)
SELECT DISTINCT class_id FROM student;

-- 5. 别名(AS,可省略):给字段/表起别名,简化代码
SELECT s.student_id AS id, s.student_name AS name FROM student s;
(3)更新数据(UPDATE)
sql 复制代码
-- 修改单条数据(必须加WHERE条件,否则修改全表!)
UPDATE student SET age = 20, class_id = 3 WHERE student_id = 1;

-- 批量修改数据
UPDATE student SET class_id = 2 WHERE gender = '女';
(4)删除数据(DELETE)
sql 复制代码
-- 删除单条数据(必须加WHERE条件,否则删除全表!)
DELETE FROM student WHERE student_id = 1;

-- 批量删除数据
DELETE FROM student WHERE class_id = 3;

三、SQL进阶语法:解锁复杂数据操作

基础语法只能处理单表数据,而实际业务中往往需要多表关联、数据聚合、分页等复杂操作,这就需要用到进阶语法。

1. 联表查询:多表数据关联(JOIN)

联表查询是进阶语法的核心,主要分为**内连接、左连接、右连接、全连接**四种,其中内连接和左连接最常用。

(1)内连接(INNER JOIN):只返回两表匹配的数据
sql 复制代码
-- 查询学生姓名及其所属班级名称(仅显示有班级的学生)
SELECT s.student_name, c.class_name
FROM student s
INNER JOIN class c ON s.class_id = c.class_id;
(2)左连接(LEFT JOIN):返回左表所有数据,右表匹配不到则为NULL
sql 复制代码
-- 查询所有学生姓名及其所属班级名称(无班级的学生也显示,班级名称为NULL)
SELECT s.student_name, c.class_name
FROM student s
LEFT JOIN class c ON s.class_id = c.class_id;
(3)右连接(RIGHT JOIN):返回右表所有数据,左表匹配不到则为NULL
sql 复制代码
-- 查询所有班级名称及其对应的学生姓名(无学生的班级也显示,学生姓名为NULL)
SELECT s.student_name, c.class_name
FROM student s
RIGHT JOIN class c ON s.class_id = c.class_id;
(4)全连接(FULL JOIN):返回两表所有数据,匹配不到则为NULL

注意 :MySQL不支持直接使用FULL JOIN,可通过UNION组合左连接和右连接实现;Oracle、SQL Server支持FULL JOIN

sql 复制代码
-- MySQL实现全连接
SELECT s.student_name, c.class_name
FROM student s
LEFT JOIN class c ON s.class_id = c.class_id
UNION
SELECT s.student_name, c.class_name
FROM student s
RIGHT JOIN class c ON s.class_id = c.class_id;

2. 子查询:嵌套在主查询中的查询语句

子查询是将一个查询结果作为另一个查询的条件或数据源,分为**标量子查询、列子查询、表子查询**。

(1)标量子查询:返回单个值(一行一列)
sql 复制代码
-- 查询与张三同班级的学生(先查张三的班级ID,再查该班级的学生)
SELECT student_name FROM student 
WHERE class_id = (SELECT class_id FROM student WHERE student_name = '张三');
(2)列子查询:返回一列数据(多行一列),使用IN/ANY/ALL
sql 复制代码
-- 查询班级1或班级2的学生(返回多个class_id)
SELECT student_name FROM student 
WHERE class_id IN (SELECT class_id FROM class WHERE class_name IN ('一班', '二班'));
(3)表子查询:返回多行多列,作为临时表
sql 复制代码
-- 查询成绩大于80分的学生姓名(先查成绩表的学生ID,再关联学生表)
SELECT s.student_name 
FROM student s
INNER JOIN (SELECT student_id FROM score WHERE score > 80) sc ON s.student_id = sc.student_id;

3. 分组与聚合:数据统计分析(GROUP BY + 聚合函数)

GROUP BY用于将数据按指定字段分组,结合聚合函数(如COUNT、SUM、AVG)实现数据统计。

sql 复制代码
-- 1. 统计每个班级的学生人数
SELECT c.class_name, COUNT(s.student_id) AS student_count
FROM class c
LEFT JOIN student s ON c.class_id = s.class_id
GROUP BY c.class_name;

-- 2. 统计每个学生的总成绩
SELECT s.student_name, SUM(sc.score) AS total_score
FROM student s
LEFT JOIN score sc ON s.student_id = sc.student_id
GROUP BY s.student_name;

-- 3. 分组后过滤(HAVING):统计学生人数大于5的班级
-- 注意:HAVING用于分组后过滤,WHERE用于分组前过滤
SELECT c.class_name, COUNT(s.student_id) AS student_count
FROM class c
LEFT JOIN student s ON c.class_id = s.class_id
GROUP BY c.class_name
HAVING student_count > 5;

4. 排序与分页:控制数据展示顺序和数量

(1)排序(ORDER BY):默认升序(ASC),降序用DESC
sql 复制代码
-- 按年龄降序、姓名升序排序
SELECT student_name, age FROM student ORDER BY age DESC, student_name ASC;
(2)分页:不同数据库语法不同,是业务中必用的语法(如列表页展示)
sql 复制代码
-- MySQL:LIMIT 偏移量, 每页条数(偏移量从0开始)
-- 示例:查询第2页数据,每页10条
SELECT student_name, age FROM student ORDER BY student_id LIMIT 10, 10;

-- Oracle:ROWNUM + 子查询
SELECT * FROM (
    SELECT s.*, ROWNUM rn FROM student s ORDER BY student_id
) WHERE rn BETWEEN 11 AND 20;

-- SQL Server:OFFSET + FETCH
SELECT student_name, age FROM student ORDER BY student_id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

四、SQL常用函数:提升数据处理效率

SQL提供了丰富的内置函数,涵盖字符串、数值、日期、聚合等类型,以下是最常用的函数示例。

1. 字符串函数

sql 复制代码
-- 1. 长度:LENGTH(MySQL)/ LEN(SQL Server)
SELECT LENGTH(student_name) AS name_length FROM student;

-- 2. 拼接:CONCAT(MySQL)/ +(SQL Server)/ ||(Oracle)
SELECT CONCAT(student_name, '-', gender) AS name_gender FROM student;

-- 3. 大小写转换:UPPER(大写)/ LOWER(小写)
SELECT UPPER(student_name) AS upper_name FROM student;

-- 4. 截取字符串:SUBSTRING(通用)
SELECT SUBSTRING(student_name, 1, 1) AS first_char FROM student; -- 截取第一个字符

2. 数值函数

sql 复制代码
-- 1. 四舍五入:ROUND
SELECT ROUND(score, 1) AS round_score FROM score; -- 保留1位小数

-- 2. 取整:CEIL(向上取整)/ FLOOR(向下取整)
SELECT CEIL(score) AS ceil_score, FLOOR(score) AS floor_score FROM score;

-- 3. 求和/平均值/最大值/最小值:SUM/AVG/MAX/MIN(聚合函数)
SELECT SUM(score) AS total, AVG(score) AS avg, MAX(score) AS max, MIN(score) AS min FROM score;

3. 日期函数

日期函数是处理时间数据的核心,不同数据库语法略有差异,以下是MySQL的常用示例:

sql 复制代码
-- 1. 获取当前时间:NOW()(日期+时间)/ CURDATE()(仅日期)/ CURTIME()(仅时间)
SELECT NOW(), CURDATE(), CURTIME();

-- 2. 日期格式化:DATE_FORMAT
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS format_time;

-- 3. 日期加减:DATE_ADD/DATE_SUB
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY) AS next_week; -- 7天后
SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH) AS last_month; -- 1个月前

-- 4. 提取日期部分:YEAR/MONTH/DAY/HOUR
SELECT YEAR(NOW()) AS year, MONTH(NOW()) AS month, DAY(NOW()) AS day;

五、SQL语法性能优化小贴士

掌握语法的同时,也要注意性能优化,避免写出"慢SQL"。以下是几个实用的优化技巧:

1. 避免使用SELECT *,只查询需要的字段

SELECT *会查询所有字段,不仅增加网络传输量,还会导致无法使用覆盖索引,严重影响性能。

2. 给查询条件字段加索引

索引是提升查询速度的关键,给WHEREJOINORDER BY等子句中的字段添加索引(如主键索引、普通索引、联合索引)。

sql 复制代码
-- 给student表的class_id字段添加普通索引
CREATE INDEX idx_student_class_id ON student(class_id);

3. 尽量使用WHERE代替HAVING

WHERE在分组前过滤数据,HAVING在分组后过滤数据,使用WHERE可以减少分组的数据量,提升性能。

4. 批量操作数据

批量插入/更新数据比单条操作效率高得多,尽量使用INSERT INTO ... VALUES (...), (...)的批量语法。

5. 避免在WHERE子句中使用函数或运算

在WHERE子句中对字段使用函数或运算,会导致索引失效,例如:

sql 复制代码
-- 错误:索引失效
SELECT * FROM student WHERE YEAR(birthday) = 2000;

-- 正确:改写为范围查询,使用索引
SELECT * FROM student WHERE birthday >= '2000-01-01' AND birthday <= '2000-12-31';

六、实战案例:综合运用SQL语法

最后,我们通过一个综合案例,将上述语法串联起来,加深理解:

需求:查询每个班级的"数学"课程平均分,且平均分大于80分,按平均分降序排列

sql 复制代码
SELECT c.class_name, AVG(sc.score) AS avg_math_score
FROM class c
LEFT JOIN student s ON c.class_id = s.class_id
LEFT JOIN score sc ON s.student_id = sc.student_id
WHERE sc.course_name = '数学'
GROUP BY c.class_name
HAVING avg_math_score > 80
ORDER BY avg_math_score DESC;

七、总结

SQL的语法体系看似繁杂,但核心逻辑是**"数据定义→数据操作→数据统计"**。对于初学者,先掌握基础的增删改查和联表查询,再逐步学习聚合函数、子查询等进阶语法;对于资深开发者,重点在于结合业务场景优化SQL性能,写出高效、可维护的代码。

记住,SQL是一门"熟能生巧"的技能,多写、多练、多分析慢查询,才能真正掌握它。希望本文的语法解析和实战案例,能帮你夯实SQL基础,应对日常开发和数据分析的需求。

相关推荐
暗之星瞳2 小时前
mysql练习
数据库·mysql
月上林梢2 小时前
QT圆形加载进度条
数据库·c++·qt·进度条
3824278272 小时前
汇编:条件汇编、
前端·汇编·数据库
蜘蛛小助理3 小时前
研发团队效率神器:手把手教你用蜘蛛表格构建自动化任务管理中枢
数据库·自动化·任务管理·多维表格·蜘蛛表格
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue酒店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Hui Baby3 小时前
全局事务入口感知子事务方法-TCC
java·开发语言·数据库
Hello.Reader3 小时前
Flink SQL EXPLAIN “看懂计划”到“用 PLAN_ADVICE 调优”
大数据·sql·flink
Leon-Ning Liu4 小时前
Oracle 19c RAC报错ORA-17503,ORA-27300,ORA-27301,ORA-27302
数据库·oracle
嘟嘟w4 小时前
DROP DELETE 和TRUNCATE的区别?
数据库·mysql·oracle