mysql数据库的条件与排序

MySQL 条件与排序完全指南

本文档专门讲 条件(WHERE)排序(ORDER BY),以及常和它们一起用的 LIMIT。每一步都配有详细说明和大量示例,适合零基础新手跟着做。


目录

  1. 条件与排序是什么
  2. 示例表说明
  3. 条件(WHERE)详解
  4. 模糊匹配:LIKE
  5. 空值判断:IS NULL / IS NOT NULL
  6. 多条件组合:AND、OR、NOT
  7. 条件优先级与括号
  8. 排序(ORDER BY)详解
  9. 限制条数:LIMIT
  10. 条件 + 排序 + LIMIT 一起用
  11. 常见错误与注意点
  12. 综合示例与速查表

1. 条件与排序是什么

1.1 条件(WHERE)

  • 条件用来筛选行:只保留满足条件的记录,不满足的不会出现在结果里。
  • 在 SQL 里用 WHERE 子句写条件,通常用在 SELECT、UPDATE、DELETE 后面。
  • 例如:“只查年龄大于 18 的学生”“只删除班级为高一2班的记录”,这里的“年龄大于 18”“班级为高一2班”就是条件。

1.2 排序(ORDER BY)

  • 排序用来决定结果按什么顺序显示:按某一列(或几列)升序或降序排。
  • 在 SQL 里用 ORDER BY 子句,一般用在 SELECT 的最后(在 WHERE 之后)。
  • 例如:“按年龄从大到小排”“先按班级排,再按姓名排”,都是排序。

1.3 条件与排序在语句中的位置

SELECT 列... FROM 表名
  WHERE  条件      -- 先筛选行
  ORDER BY 列 排序  -- 再排序
  LIMIT 条数;       -- 再限制取几条

记住顺序WHERE → ORDER BY → LIMIT(都要写在 FROM 表名 之后)。


2. 示例表说明

后面所有示例都基于下面这张 students 表,你可以先建好并插入数据,跟着练:

USE school;

CREATE TABLE IF NOT EXISTS students (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(50) NOT NULL,
    gender      CHAR(1) DEFAULT '男',
    age         INT,
    class_name  VARCHAR(20),
    score       DECIMAL(5,2),
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO students (name, gender, age, class_name, score) VALUES
('张三', '男', 18, '高一1班', 85.5),
('李四', '女', 17, '高一2班', 92.0),
('王五', '男', 18, '高一1班', 78.5),
('赵六', '女', 17, '高一2班', 88.0),
('钱七', '男', 19, '高一1班', 91.0),
('孙八', '女', 18, '高一2班', NULL),
('周九', '男', 17, '高一1班', 76.0);

表里会有 7 条记录,包含不同姓名、性别、年龄、班级、成绩(其中孙八成绩为 NULL)。


3. 条件(WHERE)详解

3.1 基本写法

SELECT 列... FROM 表名 WHERE 条件;

条件通常是一个“比较”:列 和 值(或另一列)用比较运算符连接,结果为真或假,只保留结果为真的行。

3.2 比较运算符

运算符 含义 示例
= 等于 age = 18
!= 或 不等于 age != 18
> 大于 age > 18
< 小于 age < 18
>= 大于等于 age >= 18
<= 小于等于 age <= 18

注意:判断相等用一个等号 =,不是两个(两个等号是某些编程语言里的写法,SQL 里就是一个 =)。

示例:等于

-- 年龄等于 18 的学生
SELECT * FROM students WHERE age = 18;

-- 班级等于 高一1班
SELECT * FROM students WHERE class_name = '高一1班';

-- 姓名为 张三
SELECT * FROM students WHERE name = '张三';

示例:不等于

-- 年龄不等于 18(两种写法都可以)
SELECT * FROM students WHERE age != 18;
SELECT * FROM students WHERE age <> 18;

-- 不是高一1班的学生
SELECT * FROM students WHERE class_name != '高一1班';

示例:大于、小于、大于等于、小于等于

-- 年龄大于 17
SELECT * FROM students WHERE age > 17;

-- 年龄小于 19
SELECT * FROM students WHERE age < 19;

-- 年龄大于等于 18
SELECT * FROM students WHERE age >= 18;

-- 成绩小于 80
SELECT * FROM students WHERE score < 80;

3.3 范围:BETWEEN … AND …

BETWEEN 值1 AND 值2 表示:列的值在值1和值2之间(包含值1和值2),且要求值1 ≤ 值2。

等价写法:列 >= 值1 AND 列 <= 值2

示例:年龄在 17 到 18 之间(含 17 和 18)

SELECT * FROM students WHERE age BETWEEN 17 AND 18;

示例:成绩在 80 到 90 之间(含 80 和 90)

SELECT * FROM students WHERE score BETWEEN 80 AND 90;

注意:BETWEEN 是闭区间,两边都包含;若写成 BETWEEN 18 AND 17,条件永远不成立(没有数既 ≥18 又 ≤17)。

3.4 在多个值中:IN (…)

IN (值1, 值2, 值3, …) 表示:列的值等于括号里任意一个

等价写法:列 = 值1 OR 列 = 值2 OR 列 = 值3 ...,用 IN 更简洁。

示例:学号是 1、2、3 的学生

SELECT * FROM students WHERE id IN (1, 2, 3);

示例:班级是 高一1班 或 高一2班(效果和两个班都查出来一样,这里仅演示 IN)

SELECT * FROM students WHERE class_name IN ('高一1班', '高一2班');

示例:年龄不是 17 也不是 18(NOT IN)

SELECT * FROM students WHERE age NOT IN (17, 18);

注意:IN 括号里可以是数字、字符串(加引号)、日期等,类型要和列一致。


4. 模糊匹配:LIKE

当要按“部分文字”筛选时(如“姓张的”“名字里带三的”),用 LIKE,配合两个通配符:

  • %:表示任意多个字符(包括 0 个)。
  • _(下划线):表示任意一个字符

语法: WHERE 列 LIKE '模式'

4.1 以某字符串开头:’某%’

示例:姓张的学生(姓名以“张”开头)

SELECT * FROM students WHERE name LIKE '张%';

示例:班级以“高一”开头

SELECT * FROM students WHERE class_name LIKE '高一%';

4.2 以某字符串结尾:’%某’

示例:姓名以“三”结尾

SELECT * FROM students WHERE name LIKE '%三';

4.3 包含某字符串:’%某%’

示例:姓名里包含“三”

SELECT * FROM students WHERE name LIKE '%三%';

会匹配“张三”“王三”“李三三”等。

4.4 固定长度:用下划线 _ 占位

示例:姓名恰好 2 个字(两个字符)

SELECT * FROM students WHERE name LIKE '__';

一个 _ 代表一个字符,两个就代表两个字符。

示例:姓名 3 个字,且第二个字是“小”

SELECT * FROM students WHERE name LIKE '_小_';

4.5 转义 % 和 _(了解)

若要查的字符串里本身有 % 或 _,需要转义。MySQL 默认用 转义,例如:

-- 查列值包含百分号的情况(了解即可)
WHERE col LIKE '%%%';

4.6 LIKE 小结

模式 含义 示例
‘张%’ 以“张”开头 张三、张小明
‘%三’ 以“三”结尾 张三、李三
‘%三%’ 包含“三” 张三、王三、李三三
‘__’ 恰好 2 个字符 李四、王五
共 3 字符,中间是“小” 李小华

5. 空值判断:IS NULL / IS NOT NULL

NULL 表示“没有值、未知”。
判断某列是否为空,不能= NULL(在 SQL 里,任何与 NULL 用 = 比较结果都是“未知”,不会为真),必须用:

  • IS NULL:该列是空值。
  • IS NOT NULL:该列不是空值。

示例:成绩为空的学生(没录成绩)

SELECT * FROM students WHERE score IS NULL;

示例:成绩不为空的学生

SELECT * FROM students WHERE score IS NOT NULL;

错误写法(不会得到想要的结果):

SELECT * FROM students WHERE score = NULL;   -- 错误!永远查不到
SELECT * FROM students WHERE score != NULL;  -- 错误!永远查不到

6. 多条件组合:AND、OR、NOT

6.1 AND(并且)

条件1 AND 条件2:必须同时满足条件1和条件2,才保留该行。

示例:年龄等于 18 并且 班级是高一1班

SELECT * FROM students WHERE age = 18 AND class_name = '高一1班';

示例:成绩大于等于 80 并且 成绩小于 90

SELECT * FROM students WHERE score >= 80 AND score < 90;

6.2 OR(或者)

条件1 OR 条件2:只要满足其中任意一个条件,就保留该行。

示例:班级是高一1班 或者 班级是高一2班

SELECT * FROM students WHERE class_name = '高一1班' OR class_name = '高一2班';

(这里其实等价于“班级 IN (‘高一1班’,’高一2班)’,或直接不写 WHERE 因为表里只有这两个班,仅作 OR 示例。)

示例:姓名为张三 或 姓名为李四

SELECT * FROM students WHERE name = '张三' OR name = '李四';

6.3 NOT(取反)

NOT 条件:条件为假时保留,为真时不要。

示例:不是高一2班的学生

SELECT * FROM students WHERE NOT (class_name = '高一2班');

等价于:class_name != '高一2班'class_name <> '高一2班'

示例:年龄不在 17 到 18 之间

SELECT * FROM students WHERE NOT (age BETWEEN 17 AND 18);

6.4 AND 和 OR 一起用

示例:高一1班 且 年龄大于等于 18

SELECT * FROM students WHERE class_name = '高一1班' AND age >= 18;

示例:高一1班 或 高一2班 且 年龄等于 17

注意:这里若写成 class_name = '高一1班' OR class_name = '高一2班' AND age = 17,会先算 AND 再算 OR,可能和你想的不一样(见下一节“优先级”)。
若你的意思是“(高一1班 或 高一2班) 并且 年龄=17”,要加括号:

SELECT * FROM students WHERE (class_name = '高一1班' OR class_name = '高一2班') AND age = 17;

7. 条件优先级与括号

7.1 优先级顺序(从高到低)

  1. 括号 ()
  2. NOT
  3. 比较运算符(=、>、< 等)
  4. AND
  5. OR

所以:AND 比 OR 先算

7.2 不加括号容易搞错

写法一:

SELECT * FROM students WHERE class_name = '高一1班' OR class_name = '高一2班' AND age = 18;

实际等价于:高一1班(不限年龄) 或 (高一2班 且 年龄=18)
因为先算 class_name = '高一2班' AND age = 18,再和 class_name = '高一1班' 做 OR。

若你的本意是:班级是高一1班或高一2班,并且年龄都是 18,应写成:

SELECT * FROM students WHERE (class_name = '高一1班' OR class_name = '高一2班') AND age = 18;

7.3 建议

  • 多个 ANDOR 混用时,用括号明确先算谁,避免歧义。
  • 例如:(条件1 OR 条件2) AND 条件3条件1 AND (条件2 OR 条件3)

8. 排序(ORDER BY)详解

8.1 基本语法

SELECT 列... FROM 表名 [WHERE 条件] ORDER BY 列名 [ASC | DESC];
  • ORDER BY 列名:按这一列排序。
  • ASC:升序(从小到大),默认,可省略不写。
  • DESC:降序(从大到小)。

8.2 单列排序

示例:按年龄升序(小的在前)

SELECT * FROM students ORDER BY age ASC;

或省略 ASC:

SELECT * FROM students ORDER BY age;

示例:按年龄降序(大的在前)

SELECT * FROM students ORDER BY age DESC;

示例:按成绩从高到低

SELECT * FROM students ORDER BY score DESC;

注意:排序时 NULL 会被视为“最小”,在 ASC 时排在最前,DESC 时排在最后(不同数据库可能略有差异,MySQL 默认如此)。

8.3 多列排序

先按第一列排,第一列相同再按第二列排,以此类推。

语法:

ORDER BY 列1 排序1, 列2 排序2, ...;

示例:先按班级升序,再按年龄降序

SELECT * FROM students ORDER BY class_name ASC, age DESC;

同一班级内,年龄大的在前。

示例:先按年龄降序,年龄相同再按学号升序

SELECT * FROM students ORDER BY age DESC, id ASC;

8.4 按“第几列”排序(了解)

可以用列在 SELECT 里的位置(从 1 开始)来排序,不推荐,可读性差:

SELECT name, age, class_name FROM students ORDER BY 2 DESC;

表示按第 2 列(age)降序。建议直接写列名:ORDER BY age DESC

8.5 排序小结

  • 升序:ORDER BY 列 ASCORDER BY 列
  • 降序:ORDER BY 列 DESC
  • 多列:ORDER BY 列1 ASC, 列2 DESC,先按列1,再按列2。

9. 限制条数:LIMIT

LIMIT 用来只取结果的前几条,常和 ORDER BY 一起用(先排序再取前 N 条)。

9.1 只写一个数:取前 N 条

语法: LIMIT N

示例:取前 3 条(按 id 顺序)

SELECT * FROM students ORDER BY id LIMIT 3;

示例:成绩最高的 3 名学生

SELECT * FROM students ORDER BY score DESC LIMIT 3;

(成绩为 NULL 的会按“最小”排,若想排除 NULL 可加 WHERE score IS NOT NULL。)

9.2 写两个数:跳过前 M 条,再取 N 条(分页)

语法: LIMIT 跳过条数, 取几条

  • 第一个数:跳过多少条(从 0 开始数)。
  • 第二个数:多少条。

示例:跳过前 2 条,取接下来 3 条(即第 3、4、5 条)

SELECT * FROM students ORDER BY id LIMIT 2, 3;

分页常用:每页 5 条,

  • 第 1 页:LIMIT 0, 5LIMIT 5
  • 第 2 页:LIMIT 5, 5
  • 第 3 页:LIMIT 10, 5
    即第 page 页(从 1 开始):*LIMIT (page – 1) 每页条数, 每页条数**。

MySQL 另一种写法:LIMIT N OFFSET M

SELECT * FROM students ORDER BY id LIMIT 3 OFFSET 2;

表示取 3 条,从第 3 条开始(跳过 2 条),和 LIMIT 2, 3 效果相同。


10. 条件 + 排序 + LIMIT 一起用

书写顺序(必须遵守):WHERE → ORDER BY → LIMIT

示例:高一1班的学生,按成绩从高到低,取前 2 名

SELECT * FROM students
WHERE class_name = '高一1班'
ORDER BY score DESC
LIMIT 2;

示例:年龄大于等于 17 且成绩不为空,按年龄升序、成绩降序,取前 5 条

SELECT * FROM students
WHERE age >= 17 AND score IS NOT NULL
ORDER BY age ASC, score DESC
LIMIT 5;

示例:第 2 页,每页 3 条,按 id 升序

SELECT * FROM students ORDER BY id LIMIT 3, 3;

11. 常见错误与注意点

11.1 字符串、日期要用引号

条件里的字符串、日期必须用单引号

-- 正确
WHERE name = '张三'
WHERE class_name = '高一1班'
WHERE created_at > '2025-01-01'

-- 错误(会把张三当列名等)
WHERE name = 张三

11.2 列名与关键字、空格

  • 列名若和 MySQL 关键字相同,或包含空格、特殊字符,要用反引号包起来,例如 `order`、`class name`。
  • 一般命名避免用关键字和空格即可。

11.3 NULL 必须用 IS NULL / IS NOT NULL

不要写 = NULL!= NULL,结果不会符合预期。

11.4 LIKE 的通配符

  • %_ 在 LIKE 里有特殊含义;若数据里本身有 %、_,需要转义(见 4.5 节)。

11.5 ORDER BY 和 LIMIT 的位置

  • ORDER BY 必须在 WHERE 之后、LIMIT 之前。
  • 错误示例:SELECT * FROM students LIMIT 3 ORDER BY age;(会报错)。

12. 综合示例与速查表

12.1 综合示例(可整段执行)

USE school;

-- 条件:年龄 18,且班级高一1班
SELECT * FROM students WHERE age = 18 AND class_name = '高一1班';

-- 条件:成绩在 80~90 之间(含)
SELECT * FROM students WHERE score BETWEEN 80 AND 90;

-- 条件:id 在 1,2,3 中
SELECT * FROM students WHERE id IN (1, 2, 3);

-- 模糊:姓张
SELECT * FROM students WHERE name LIKE '张%';

-- 空值:成绩为空
SELECT * FROM students WHERE score IS NULL;

-- 排序:按成绩降序,取前 3
SELECT * FROM students WHERE score IS NOT NULL ORDER BY score DESC LIMIT 3;

-- 条件 + 排序 + 分页:高一1班,按成绩降序,第 1 页每页 2 条
SELECT * FROM students WHERE class_name = '高一1班' ORDER BY score DESC LIMIT 0, 2;

12.2 条件与排序速查表

需求 写法示例
等于 WHERE 列 = 值
不等于 WHERE 列 != 值WHERE 列 <> 值
大于/小于 WHERE 列 > 值WHERE 列 < 值>=<=
范围(含两端) WHERE 列 BETWEEN 值1 AND 值2
在多个值中 WHERE 列 IN (值1, 值2)
不在多个值中 WHERE 列 NOT IN (值1, 值2)
以某串开头 WHERE 列 LIKE '某%'
包含某串 WHERE 列 LIKE '%某%'
为空 WHERE 列 IS NULL
非空 WHERE 列 IS NOT NULL
并且 WHERE 条件1 AND 条件2
或者 WHERE 条件1 OR 条件2
取反 WHERE NOT 条件
升序 ORDER BY 列 ASCORDER BY 列
降序 ORDER BY 列 DESC
多列排序 ORDER BY 列1 ASC, 列2 DESC
取前 N 条 LIMIT N
分页 LIMIT 跳过, 条数LIMIT 条数 OFFSET 跳过

子句顺序WHERE → ORDER BY → LIMIT


把「条件」和「排序」练熟后,配合前面的 增删改查,你就能完成大部分单表查询和筛选。建议在本地用 students 表把本文示例都跑一遍,再自己改条件、改排序、改 LIMIT 多试几种组合。

发表评论