基础查询
基础查询
想象你走进一家图书馆,想要找一本书。你不会把整个图书馆的书都搬回家,而是告诉图书管理员:"我想找2020年以后出版的科幻小说,按出版日期从新到旧排列,给我看前5本。"这个过程就对应了SQL查询的核心步骤:选择数据、过滤条件、排序、限制数量。
在上一课中,我们学会了如何创建数据库和表,并插入了数据。本课将学习如何从数据库中精确地查询我们需要的数据。
核心概念
1. SELECT 语句
SELECT 是SQL中最常用的语句,用于从数据库表中检索数据。它的基本结构如下:
SELECT 列名1, 列名2, ...
FROM 表名;
SELECT后面指定要查询的列FROM后面指定从哪张表中查询- 每条SQL语句以分号
;结尾
2. 查询特定列与查询所有列
查询特定列(推荐):
SELECT name, salary FROM employees;
查询所有列:
SELECT * FROM employees;
*。这样可以提高查询效率,也使代码更清晰。
3. WHERE 条件过滤
WHERE 子句用于过滤记录,只返回满足条件的行:
SELECT 列名1, 列名2
FROM 表名
WHERE 条件;
4. 比较运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
= |
等于 | salary = 50000 |
<> 或 != |
不等于 | status <> '离职' |
> |
大于 | salary > 50000 |
< |
小于 | age < 30 |
>= |
大于等于 | salary >= 50000 |
<= |
小于等于 | age <= 30 |
5. 逻辑运算符:AND / OR
AND:所有条件都必须为真OR:至少一个条件为真
SELECT name, salary, department_id
FROM employees
WHERE salary > 50000 AND department_id = 1;
SELECT name, salary, department_id
FROM employees
WHERE department_id = 1 OR department_id = 2;
AND 和 OR 混合使用时,AND 的优先级更高。建议使用括号 () 来明确优先级,避免歧义。
6. IN / BETWEEN / LIKE
IN — 匹配一组值中的任意一个:
SELECT name, department_id
FROM employees
WHERE department_id IN (1, 2, 3);
BETWEEN — 匹配一个范围内的值(包含边界):
SELECT name, salary
FROM employees
WHERE salary BETWEEN 40000 AND 80000;
LIKE — 模糊匹配字符串:
%匹配任意数量的字符(包括零个)_匹配恰好一个字符
-- 名字以"张"开头的员工
SELECT name FROM employees WHERE name LIKE '张%';
-- 名字是两个字且姓"李"的员工
SELECT name FROM employees WHERE name LIKE '李_';
7. ORDER BY 排序
ORDER BY 用于对结果集进行排序:
ASC:升序(默认,可省略)DESC:降序
-- 按薪资从高到低排序
SELECT name, salary
FROM employees
ORDER BY salary DESC;
-- 先按部门升序,再按薪资降序
SELECT name, department_id, salary
FROM employees
ORDER BY department_id ASC, salary DESC;
8. LIMIT 限制行数
LIMIT 用于限制返回的记录数量:
-- 只返回前5条记录
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;
-- 跳过前5条,返回接下来的5条(分页)
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5 OFFSET 5;
LIMIT 通常与 ORDER BY 配合使用,否则返回的记录顺序是不确定的。
基本语法/用法
查询语句的完整结构
SELECT 列名1, 列名2, ...
FROM 表名
WHERE 条件
ORDER BY 列名 [ASC|DESC]
LIMIT 数量 [OFFSET 偏移量];
各子句的书写顺序必须严格遵守:
| 顺序 | 子句 | 作用 |
|---|---|---|
| 1 | SELECT |
指定要查询的列 |
| 2 | FROM |
指定数据来源的表 |
| 3 | WHERE |
过滤行 |
| 4 | ORDER BY |
排序结果 |
| 5 | LIMIT |
限制返回行数 |
常用技巧
-- 使用别名让列名更易读
SELECT name AS 姓名, salary AS 薪资
FROM employees;
-- 去除重复值
SELECT DISTINCT department_id
FROM employees;
-- 在SELECT中使用表达式
SELECT name, salary, salary * 12 AS 年薪
FROM employees;
- 别名可以用中文,但在团队协作中建议使用英文
DISTINCT会对所有选中的列组合去重- 表达式不会修改原始数据,只影响查询结果的显示
示例
示例:查询特定部门的员工
需求:查询部门ID为1的所有员工姓名和薪资,按薪资从高到低排列。
SELECT name, salary
FROM employees
WHERE department_id = 1
ORDER BY salary DESC;
预期输出:
+--------+--------+
| name | salary |
+--------+--------+
| 张三 | 85000 |
| 王五 | 62000 |
| 赵六 | 55000 |
+--------+--------+
解析:
WHERE department_id = 1只保留部门ID为1的行ORDER BY salary DESC按薪资降序排列- 结果只包含
name和salary两列
示例:多条件组合查询
需求:查询薪资在60000到90000之间、且部门ID为1或2的员工,显示姓名、部门ID和薪资,按部门ID升序、薪资降序排列。
SELECT name, department_id, salary
FROM employees
WHERE salary BETWEEN 60000 AND 90000
AND department_id IN (1, 2)
ORDER BY department_id ASC, salary DESC;
预期输出:
+--------+---------------+--------+
| name | department_id | salary |
+--------+---------------+--------+
| 张三 | 1 | 85000 |
| 王五 | 1 | 62000 |
| 李四 | 2 | 75000 |
+--------+---------------+--------+
解析:
BETWEEN 60000 AND 90000筛选薪资范围IN (1, 2)筛选部门AND组合两个条件- 排序先按部门升序,部门相同时按薪资降序
示例:模糊查询与分页
需求:查找名字中包含"张"字的员工,按入职日期降序排列,只显示第2到第3条记录。
SELECT name, hire_date, salary
FROM employees
WHERE name LIKE '%张%'
ORDER BY hire_date DESC
LIMIT 2 OFFSET 1;
预期输出:
+--------+------------+--------+
| name | hire_date | salary |
+--------+------------+--------+
| 张伟 | 2022-03-15 | 68000 |
| 张敏 | 2021-08-20 | 52000 |
+--------+------------+--------+
解析:
LIKE '%张%'匹配名字中任意位置包含"张"的记录ORDER BY hire_date DESC按入职日期从新到旧排列LIMIT 2 OFFSET 1跳过第1条,返回第2和第3条(即分页的第2页,每页2条)
场景
场景一:按薪资范围筛选高薪员工
HR需要导出一份薪资超过70000的员工名单,包含姓名、部门和薪资,按薪资从高到低排列。
SELECT e.name AS 员工姓名,
d.name AS 部门名称,
e.salary AS 薪资
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.salary > 70000
ORDER BY e.salary DESC;
说明:
- 使用
JOIN关联部门表以获取部门名称(将在后续课程详细讲解) e和d是表的别名,简化书写- 别名使用中文,让输出结果更直观
场景二:分页展示员工列表
Web应用的员工列表页面,每页显示10条记录,用户点击第3页时,需要跳过前20条,显示第21-30条。
-- 第3页,每页10条
SELECT id, name, department_id, salary
FROM employees
ORDER BY id ASC
LIMIT 10 OFFSET 20;
分页公式:OFFSET = (页码 - 1) × 每页条数
| 页码 | LIMIT | OFFSET |
|---|---|---|
| 第1页 | 10 | 0 |
| 第2页 | 10 | 10 |
| 第3页 | 10 | 20 |
❓ 常见问题
Q:
SELECT *和指定列名有什么区别? A:SELECT *返回表中所有列,而指定列名只返回需要的列。在生产环境中,建议明确指定列名,这样查询速度更快、可读性更好,也能避免表结构变更时出错。
Q:
WHERE中能使用别名吗? A: 不能。SQL的执行顺序是FROM→WHERE→SELECT→ORDER BY,WHERE执行时还没有生成别名。如果需要按别名过滤,可以使用子查询或HAVING(后续课程讲解)。
Q:
BETWEEN包含边界值吗? A: 包含。BETWEEN 10 AND 20等价于>= 10 AND <= 20,两端的值都会被包含在结果中。
Q:
LIKE查询区分大小写吗? A: 取决于数据库的排序规则(Collation)。MySQL默认不区分大小写,PostgreSQL默认区分。如需强制区分大小写,PostgreSQL可使用LIKE,MySQL可使用BINARY关键字。
📖 小节
本课学习了SQL查询的核心技能:
- SELECT — 指定要查询的列,可用
*查询所有列 - WHERE — 用条件过滤行,支持比较运算符(
=,>,<,<>,>=,<=) - 逻辑运算符 —
AND(且)、OR(或),可用括号控制优先级 - IN — 匹配一组值中的任意一个
- BETWEEN — 匹配一个范围内的值(包含边界)
- LIKE — 模糊匹配,
%匹配多个字符,_匹配单个字符 - ORDER BY — 排序,
ASC升序(默认),DESC降序 - LIMIT / OFFSET — 限制返回行数,实现分页
查询语句的书写顺序:SELECT → FROM → WHERE → ORDER BY → LIMIT
📝 作业
练习一:基础查询
查询 departments 表中的所有记录,只显示 name 和 location 两列。
练习二:条件过滤与排序
查询 employees 表中薪资大于等于60000且入职日期在2022年1月1日之后的员工,显示姓名、薪资和入职日期,按薪资降序排列。
练习三:综合查询
查询 employees 表中部门ID为1或3、且名字不以"张"开头的员工,显示姓名、部门ID和薪资,按部门ID升序、薪资降序排列,只返回前3条记录。



