SQL 语句大全实例教程
目录
-
(图片来源网络,侵删) -
(图片来源网络,侵删)
准备工作:示例数据库
为了让大家更好地理解,我们先创建一个简单的示例数据库和几张表。
表1: users (用户表)
| id | name | email | city | registration_date |
|----|------|-------|------|-------------------|
| 1 | 张三 | zhangsan@email.com | 北京 | 2025-01-15 |
| 2 | 李四 | lisi@email.com | 上海 | 2025-02-20 |
| 3 | 王五 | wangwu@email.com | 北京 | 2025-03-10 |
| 4 | 赵六 | zhaoliu@email.com | 广州 | 2025-04-05 |
| 5 | 孙七 | sunqi@email.com | 上海 | 2025-05-12 |

表2: orders (订单表)
| id | user_id | product_name | amount | order_date |
|----|---------|-------------|--------|------------|
| 101 | 1 | 笔记本电脑 | 5999 | 2025-06-01 |
| 102 | 2 | 鼠标 | 99 | 2025-06-02 |
| 103 | 1 | 键盘 | 199 | 2025-06-03 |
| 104 | 3 | 显示器 | 1299 | 2025-06-04 |
| 105 | 2 | 笔记本电脑 | 5999 | 2025-06-05 |
| 106 | 4 | 耳机 | 299 | 2025-06-06 |
第一部分:SQL 基础
1 什么是 SQL?
SQL (Structured Query Language) 是一种用于管理关系型数据库的标准化语言,它可以用于创建、查询、更新和删除数据库中的数据。
2 数据库与表
数据库是表的集合,表是行的集合。
CREATE DATABASE mydb;(创建数据库)USE mydb;(使用数据库)CREATE TABLE users (...);(创建表)
3 SELECT - 查询数据
SELECT 语句用于从数据库中获取数据。
语法:
SELECT column1, column2, ... FROM table_name;
实例:
-- 查询所有用户的姓名和邮箱 SELECT name, email FROM users;
结果: | name | email | |------|-------| | 张三 | zhangsan@email.com | | 李四 | lisi@email.com | | ... | ... |
*通配符 ``:**
-- 查询 users 表的所有字段 SELECT * FROM users;
4 FROM - 指定来源
FROM 子句用于指定从哪个表中查询数据。
实例:
-- 从 orders 表中查询所有订单信息 SELECT * FROM orders;
5 WHERE - 过滤数据
WHERE 子句用于根据指定条件过滤记录。
语法:
SELECT column1, column2 FROM table_name WHERE condition;
实例:
-- 查询所有来自北京的用户 SELECT name, city FROM users WHERE city = '北京';
结果: | name | city | |------|------| | 张三 | 北京 | | 王五 | 北京 |
6 AND / OR - 多条件组合
AND 和 OR 用于组合多个条件。
实例:
-- 查询来自北京且注册日期在 2025-02-01 之后的用户 SELECT name, city, registration_date FROM users WHERE city = '北京' AND registration_date > '2025-02-01'; -- 查询来自北京或上海的用户 SELECT name, city FROM users WHERE city = '北京' OR city = '上海';
7 ORDER BY - 排序结果
ORDER BY 子句用于对结果集进行排序,默认为升序 (ASC),可指定为降序 (DESC)。
语法:
SELECT column1, column2 FROM table_name ORDER BY column1 ASC/DESC, column2 ASC/DESC;
实例:
-- 按注册日期升序排列用户 SELECT name, registration_date FROM users ORDER BY registration_date; -- 按订单金额降序排列订单 SELECT product_name, amount FROM orders ORDER BY amount DESC;
8 LIMIT - 限制结果数量
LIMIT 子句用于限制返回的记录数。
语法:
SELECT column1, column2 FROM table_name LIMIT number;
(注意:MySQL/PostgreSQL 使用 LIMIT,SQL Server 使用 TOP,Oracle 使用 FETCH FIRST)
实例:
-- 查询金额最高的前3个订单 SELECT product_name, amount FROM orders ORDER BY amount DESC LIMIT 3;
第二部分:进阶查询
1 DISTINCT - 去除重复值
DISTINCT 关键字用于返回唯一不同的值。
实例:
-- 查询所有用户来自的城市(不重复) SELECT DISTINCT city FROM users;
结果: | city | |------| | 北京 | | 上海 | | 广州 |
2 LIKE - 模糊查询
LIKE 操作符用于在 WHERE 子句中进行搜索匹配。
- 代表零个、一个或多个字符。
_:代表单个字符。
实例:
-- 查询邮箱以 'email.com' 结尾的用户 SELECT name, email FROM users WHERE email LIKE '%email.com'; -- 查询姓'张'的用户 SELECT name FROM users WHERE name LIKE '张%'; -- 查询名字是两个字符的用户 SELECT name FROM users WHERE name LIKE '__';
3 IN / NOT IN - 范围查询
IN 操作符允许你在 WHERE 子句中指定多个值。
实例:
-- 查询来自北京或上海的用户
SELECT name, city FROM users WHERE city IN ('北京', '上海');
-- 查询订单产品不是 '笔记本电脑' 的订单
SELECT product_name, amount FROM orders WHERE product_name NOT IN ('笔记本电脑');
4 BETWEEN - 范围查询(数值/日期)
BETWEEN 操作符选取介于两个值之间的数据范围(包含边界)。
实例:
-- 查询订单金额在 100 到 1000 之间的订单 SELECT product_name, amount FROM orders WHERE amount BETWEEN 100 AND 1000; -- 查询在 2025年6月3日 到 2025年6月5日 之间的订单 SELECT * FROM orders WHERE order_date BETWEEN '2025-06-03' AND '2025-06-05';
5 IS NULL / IS NOT NULL - 空值判断
用于检查字段是否为空值。
实例:
-- 假设 users 表有一个 phone 字段,可能为空 -- 查询没有填写手机号的用户 SELECT name FROM users WHERE phone IS NULL; -- 查询填写了手机号的用户 SELECT name FROM users WHERE phone IS NOT NULL;
6 GROUP BY - 分组数据
GROUP BY 语句将结果集按一个或多个列进行分组,通常与聚合函数一起使用。
实例:
-- 按 city 分组,计算每个城市的用户数量 SELECT city, COUNT(*) AS user_count FROM users GROUP BY city;
结果: | city | user_count | |------|------------| | 北京 | 2 | | 上海 | 2 | | 广州 | 1 |
7 HAVING - 过滤分组
HAVING 子句用于过滤 GROUP BY 之后的分组结果,类似于 WHERE,但 WHERE 是在分组前过滤行,HAVING 是在分组后过滤组。
实例:
-- 找出用户数量大于1的城市 SELECT city, COUNT(*) AS user_count FROM users GROUP BY city HAVING COUNT(*) > 1;
结果: | city | user_count | |------|------------| | 北京 | 2 | | 上海 | 2 |
8 COUNT, SUM, AVG, MAX, MIN - 聚合函数
这些函数对一组值执行计算,并返回单个值。
COUNT(*): 计算行数。SUM(column): 计算某列的总和。AVG(column): 计算某列的平均值。MAX(column): 返回某列的最大值。MIN(column): 返回某列的最小值。
实例:
-- 计算订单总数 SELECT COUNT(*) AS total_orders FROM orders; -- 计算所有订单的总金额和平均金额 SELECT SUM(amount) AS total_sales, AVG(amount) AS avg_order_value FROM orders; -- 找出最高和最低的订单金额 SELECT MAX(amount) AS max_amount, MIN(amount) AS min_amount FROM orders;
第三部分:多表查询
1 JOIN - 连接表
JOIN 用于根据两个或多个表之间的相关字段,将这些表的行结合起来。
2 INNER JOIN - 内连接
返回两个表中匹配的记录,只保留两边都存在的数据。
语法:
SELECT columns FROM table1 INNER JOIN table2 ON table1.common_column = table2.common_column;
实例:
-- 查询所有订单及其对应的用户姓名
SELECT
o.id AS order_id,
o.product_name,
o.amount,
u.name AS user_name
FROM
orders o
INNER JOIN
users u ON o.user_id = u.id;
结果: | order_id | product_name | amount | user_name | |----------|--------------|--------|-----------| | 101 | 笔记本电脑 | 5999 | 张三 | | 102 | 鼠标 | 99 | 李四 | | 103 | 键盘 | 199 | 张三 | | ... | ... | ... | ... |
3 LEFT JOIN / RIGHT JOIN - 左/右连接
LEFT JOIN: 返回左表(FROM指定的表)的所有记录,以及右表中匹配的记录,如果右表没有匹配,则结果中右表的列为NULL。RIGHT JOIN: 与LEFT JOIN相反,返回右表的所有记录。
实例 (LEFT JOIN):
-- 查询所有用户及其订单(包括没有订单的用户)
SELECT
u.name AS user_name,
o.product_name,
o.amount
FROM
users u
LEFT JOIN
orders o ON u.id = o.user_id;
结果: | user_name | product_name | amount | |-----------|--------------|--------| | 张三 | 笔记本电脑 | 5999 | | 张三 | 键盘 | 199 | | 李四 | 鼠标 | 99 | | 李四 | 笔记本电脑 | 5999 | | 王五 | 显示器 | 1299 | | 赵六 | 耳机 | 299 | | 孙七 | NULL | NULL | <-- 孙七没有订单
4 FULL OUTER JOIN - 全外连接
返回左右两个表中的所有记录,如果某一边没有匹配,则另一边的列为 NULL。
(注意:MySQL 不支持 FULL OUTER JOIN,但可以通过 LEFT JOIN + UNION + RIGHT JOIN 来模拟)
语法 (标准SQL):
SELECT columns FROM table1 FULL OUTER JOIN table2 ON table1.common_column = table2.common_column;
5 UNION / UNION ALL - 合并结果集
UNION: 合并两个或多个SELECT语句的结果,并自动去除重复的行。UNION ALL: 合并结果,但不去除重复的行,性能通常更好。
实例:
-- 假设有一个 'products' 表,想获取所有用户名和产品名 SELECT name FROM users UNION SELECT product_name FROM orders;
第四部分:数据操作语言
1 INSERT INTO - 插入数据
用于向表中插入新行。
语法:
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
实例:
-- 向 users 表中插入一个新用户
INSERT INTO users (name, email, city, registration_date)
VALUES ('周八', 'zhouba@email.com', '深圳', '2025-07-01');
2 UPDATE - 更新数据
用于更新表中的现有记录。
⚠️ 警告: 务必在 UPDATE 语句中使用 WHERE 子句,否则会更新表中的所有行!
语法:
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
实例:
-- 将用户 '张三' 的邮箱更新为 new_email@email.com UPDATE users SET email = 'new_email@email.com' WHERE name = '张三';
3 DELETE - 删除数据
用于删除表中的行。
⚠️ 警告: 务必在 DELETE 语句中使用 WHERE 子句,否则会删除表中的所有行!
语法:
DELETE FROM table_name WHERE condition;
实例:
-- 删除用户 '周八' 的记录 DELETE FROM users WHERE name = '周八';
第五部分:数据定义语言
1 CREATE TABLE - 创建表
用于创建新表。
语法:
CREATE TABLE table_name (
column1 datatype constraint,
column2 datatype constraint,
...
);
实例:
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(100) NOT NULL,
price DECIMAL(10, 2) NOT NULL
);
2 ALTER TABLE - 修改表结构
用于在现有表中添加、删除或修改列。
实例:
-- 向 users 表添加一个 phone 列 ALTER TABLE users ADD COLUMN phone VARCHAR(20); -- 删除 users 表的 phone 列 ALTER TABLE users DROP COLUMN phone;
3 DROP TABLE - 删除表
用于删除表及其所有数据、索引、触发器等。
⚠️ 警告: 此操作不可逆!
语法:
DROP TABLE table_name;
第六部分:高级主题
1 子查询
嵌套在其他查询中的 SELECT 语句,通常放在 WHERE、FROM 或 SELECT 子句中。
实例 (在 WHERE 中使用):
-- 查购买了 '笔记本电脑' 的用户信息
SELECT * FROM users
WHERE id IN (
SELECT user_id FROM orders WHERE product_name = '笔记本电脑'
);
2 窗口函数
对一组行执行计算,但与聚合函数不同,它们不会将多行压缩成一行,常用于排名、计算移动平均值等。
常用窗口函数:ROW_NUMBER(), RANK(), DENSE_RANK(), SUM() OVER(), AVG() OVER()
实例 (为每个订单按金额排名):
SELECT
id,
product_name,
amount,
RANK() OVER (ORDER BY amount DESC) AS sales_rank
FROM orders;
结果: | id | product_name | amount | sales_rank | |----|--------------|--------|------------| | 101 | 笔记本电脑 | 5999 | 1 | | 105 | 笔记本电脑 | 5999 | 1 | | 104 | 显示器 | 1299 | 3 | | 103 | 键盘 | 199 | 4 | | ... | ... | ... | ... |
3 索引
索引是提高数据库查询性能的数据库对象,它就像一本书的目录,可以快速定位数据。
创建索引:
CREATE INDEX idx_user_name ON users(name);
第七部分:实战案例
场景:分析电商销售数据,回答以下问题:
- 找出每个用户购买的总金额。
- 找出消费总金额最高的用户是谁?
- 找出每个城市消费总金额,并按消费总额降序排列。
解答:
问题1: 找出每个用户购买的总金额。
需要将 orders 表按 user_id 分组,然后对 amount 求和。
SELECT
o.user_id,
u.name AS user_name,
SUM(o.amount) AS total_spent
FROM
orders o
JOIN
users u ON o.user_id = u.id
GROUP BY
o.user_id, u.name;
问题2: 找出消费总金额最高的用户是谁?
在问题1的基础上,按 total_spent 降序排列,并只取第一行。
SELECT
u.name AS user_name,
SUM(o.amount) AS total_spent
FROM
orders o
JOIN
users u ON o.user_id = u.id
GROUP BY
u.name
ORDER BY
total_spent DESC
LIMIT 1;
(注意:如果存在消费金额并列最高的用户,LIMIT 1 只会返回一个,使用窗口函数可以更好地处理这种情况。)
问题3: 找出每个城市消费总金额,并按消费总额降序排列。
需要将 orders 和 users 表连接,然后按 city 分组,对 amount 求和,最后排序。
SELECT
u.city,
SUM(o.amount) AS city_total_sales
FROM
orders o
JOIN
users u ON o.user_id = u.id
GROUP BY
u.city
ORDER BY
city_total_sales DESC;
这份教程涵盖了 SQL 最核心和最常用的语句,学习 SQL 的最佳方式就是多动手实践,你可以尝试用这些语句去操作你自己的数据库,或者创建更复杂的场景来挑战自己。
- 基础 (DQL):
SELECT,FROM,WHERE,ORDER BY,LIMIT是每天都要用的。 - 进阶:
GROUP BY,HAVING,JOIN是进行数据分析的关键。 - 操作 (DML):
INSERT,UPDATE,DELETE用于管理数据。 - 定义 (DDL):
CREATE,ALTER,DROP用于构建数据库结构。
希望这份大全能成为你学习和工作中方便的查询手册!
