404 Not Found

404 Not Found


nginx

基础查询

基础查询

想象你走进一家图书馆,想要找一本书。你不会把整个图书馆的书都搬回家,而是告诉图书管理员:"我想找2020年以后出版的科幻小说,按出版日期从新到旧排列,给我看前5本。"这个过程就对应了SQL查询的核心步骤:选择数据过滤条件排序限制数量

在上一课中,我们学会了如何创建数据库和表,并插入了数据。本课将学习如何从数据库中精确地查询我们需要的数据。


核心概念

1. SELECT 语句

SELECT 是SQL中最常用的语句,用于从数据库表中检索数据。它的基本结构如下:

SQL
SELECT 列名1, 列名2, ...
FROM 表名;

2. 查询特定列与查询所有列

查询特定列(推荐):

SQL
SELECT name, salary FROM employees;

查询所有列:

SQL
SELECT * FROM employees;
💡 提示:在实际开发中,建议明确指定需要的列名,而不是使用 *。这样可以提高查询效率,也使代码更清晰。

3. WHERE 条件过滤

WHERE 子句用于过滤记录,只返回满足条件的行:

SQL
SELECT 列名1, 列名2
FROM 表名
WHERE 条件;

4. 比较运算符

运算符 说明 示例
= 等于 salary = 50000
<>!= 不等于 status <> '离职'
> 大于 salary > 50000
< 小于 age < 30
>= 大于等于 salary >= 50000
<= 小于等于 age <= 30

5. 逻辑运算符:AND / OR

SQL
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;
💡 提示:当 ANDOR 混合使用时,AND 的优先级更高。建议使用括号 () 来明确优先级,避免歧义。

6. IN / BETWEEN / LIKE

IN — 匹配一组值中的任意一个:

SQL
SELECT name, department_id
FROM employees
WHERE department_id IN (1, 2, 3);

BETWEEN — 匹配一个范围内的值(包含边界):

SQL
SELECT name, salary
FROM employees
WHERE salary BETWEEN 40000 AND 80000;

LIKE — 模糊匹配字符串:

SQL
-- 名字以"张"开头的员工
SELECT name FROM employees WHERE name LIKE '张%';

-- 名字是两个字且姓"李"的员工
SELECT name FROM employees WHERE name LIKE '李_';

7. ORDER BY 排序

ORDER BY 用于对结果集进行排序:

SQL
-- 按薪资从高到低排序
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 用于限制返回的记录数量:

SQL
-- 只返回前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 配合使用,否则返回的记录顺序是不确定的。


基本语法/用法

查询语句的完整结构

SQL
SELECT 列名1, 列名2, ...
FROM 表名
WHERE 条件
ORDER BY 列名 [ASC|DESC]
LIMIT 数量 [OFFSET 偏移量];

各子句的书写顺序必须严格遵守:

顺序 子句 作用
1 SELECT 指定要查询的列
2 FROM 指定数据来源的表
3 WHERE 过滤行
4 ORDER BY 排序结果
5 LIMIT 限制返回行数

常用技巧

SQL
-- 使用别名让列名更易读
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的所有员工姓名和薪资,按薪资从高到低排列。

SQL
SELECT name, salary
FROM employees
WHERE department_id = 1
ORDER BY salary DESC;
▶ 试一试

预期输出

TEXT
+--------+--------+
| name   | salary |
+--------+--------+
| 张三   |  85000 |
| 王五   |  62000 |
| 赵六   |  55000 |
+--------+--------+

解析

示例:多条件组合查询

需求:查询薪资在60000到90000之间、且部门ID为1或2的员工,显示姓名、部门ID和薪资,按部门ID升序、薪资降序排列。

SQL
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;
▶ 试一试

预期输出

TEXT
+--------+---------------+--------+
| name   | department_id | salary |
+--------+---------------+--------+
| 张三   |             1 |  85000 |
| 王五   |             1 |  62000 |
| 李四   |             2 |  75000 |
+--------+---------------+--------+

解析

示例:模糊查询与分页

需求:查找名字中包含"张"字的员工,按入职日期降序排列,只显示第2到第3条记录。

SQL
SELECT name, hire_date, salary
FROM employees
WHERE name LIKE '%张%'
ORDER BY hire_date DESC
LIMIT 2 OFFSET 1;
▶ 试一试

预期输出

TEXT
+--------+------------+--------+
| name   | hire_date  | salary |
+--------+------------+--------+
| 张伟   | 2022-03-15 |  68000 |
| 张敏   | 2021-08-20 |  52000 |
+--------+------------+--------+

解析


场景

场景一:按薪资范围筛选高薪员工

HR需要导出一份薪资超过70000的员工名单,包含姓名、部门和薪资,按薪资从高到低排列。

SQL
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;

说明

场景二:分页展示员工列表

Web应用的员工列表页面,每页显示10条记录,用户点击第3页时,需要跳过前20条,显示第21-30条。

SQL
-- 第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的执行顺序是 FROMWHERESELECTORDER BYWHERE 执行时还没有生成别名。如果需要按别名过滤,可以使用子查询或 HAVING(后续课程讲解)。

Q:BETWEEN 包含边界值吗? A: 包含。BETWEEN 10 AND 20 等价于 >= 10 AND <= 20,两端的值都会被包含在结果中。

Q:LIKE 查询区分大小写吗? A: 取决于数据库的排序规则(Collation)。MySQL默认不区分大小写,PostgreSQL默认区分。如需强制区分大小写,PostgreSQL可使用 LIKE,MySQL可使用 BINARY 关键字。


📖 小节

本课学习了SQL查询的核心技能:

  1. SELECT — 指定要查询的列,可用 * 查询所有列
  2. WHERE — 用条件过滤行,支持比较运算符(=, >, <, <>, >=, <=
  3. 逻辑运算符AND(且)、OR(或),可用括号控制优先级
  4. IN — 匹配一组值中的任意一个
  5. BETWEEN — 匹配一个范围内的值(包含边界)
  6. LIKE — 模糊匹配,% 匹配多个字符,_ 匹配单个字符
  7. ORDER BY — 排序,ASC 升序(默认),DESC 降序
  8. LIMIT / OFFSET — 限制返回行数,实现分页

查询语句的书写顺序:SELECTFROMWHEREORDER BYLIMIT


📝 作业

练习一:基础查询

查询 departments 表中的所有记录,只显示 namelocation 两列。

练习二:条件过滤与排序

查询 employees 表中薪资大于等于60000且入职日期在2022年1月1日之后的员工,显示姓名、薪资和入职日期,按薪资降序排列。

练习三:综合查询

查询 employees 表中部门ID为1或3、且名字不以"张"开头的员工,显示姓名、部门ID和薪资,按部门ID升序、薪资降序排列,只返回前3条记录。


下一课:数据操作:INSERT、UPDATE、DELETE

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏