数据查询语言 DQL

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: SELECT 是 MySQL 里用得最多的语句之一,很多小伙伴用起来却总有点迷糊,比如 WHERE 和 HAVING 到底啥区别,GROUP BY 怎么配合聚合函数用,LIMIT 和 ORDER BY 组合排序到底先干啥……这篇文章就带你一块理清 SELECT 的执行顺序,讲透常用条件筛选写法,配了不少例子,学完用起来更顺手!

作者:IvanCodes
日期:2025年6月6日

核心目标: 学习如何使用 select 语句从数据库表中高效、准确地检索(查询)所需数据。

基本语法结构(逻辑顺序概览):

select [distinct] column_list_or_expressions -- 5. 选择并处理列
from table_name                            -- 1. 确定数据源表
[where conditions]                         -- 2. 过滤行
[group by column_list]                     -- 3. 分组行
[having conditions_on_groups]              -- 4. 过滤分组
[order by column_list [asc | desc]]        -- 6. 排序结果
[limit [offset,] row_count];               -- 7. 限制输出行数
AI 代码解读

(注意:以上数字表示逻辑执行顺序,并非书写顺序)

前提: 操作前需使用 use database_name; 选择目标数据库。以下示例假设已选定数据库,并使用 studentsproducts 表。

1. 数据源

指定要从哪个(或哪些)表中检索数据。

  • 语法: ... from table_name [alias] ...
  • 表别名 (as 或省略 as): 为表指定临时名称,提高可读性,尤其在 JOIN 时。

示例:

-- 使用别名 s
select s.first_name, s.major from students as s;
-- 省略 as
select p.product_name from products p;
AI 代码解读

2. 行过滤 (where)

根据指定条件筛选出符合要求的行。在分组 (group by) 之前执行。

  • 语法: ... where condition;

  • 常用条件运算符/子句 :

    | 运算符 / 子句 | 含义 | 示例 (仅示意) |
    | :-------------------------- | :------------------------------------ | :----------------------------------- |
    | = | 等于 | where major = '物理学' |
    | > | 大于 | where price > 100 |
    | < | 小于 | where gpa < 3.0 |
    | >= | 大于等于 | where stock_quantity >= 50 |
    | <= | 小于等于 | where price <= 500 |
    | !=<> | 不等于 | where major != '化学' |
    | and | 逻辑与 (所有条件需满足) | where major = 'CS' and gpa > 3.5 |
    | or | 逻辑或 (任一条件满足即可) | where price < 100 or stock = 0 |
    | not | 逻辑非 (条件不成立) | where not major = '金融学' |
    | between value1 and value2 | 在 value1 和 value2 之间 (含边界) | where price between 100 and 500 |
    | in (val1, val2, ...) | 值在列表中 | where major in ('物理', '化学') |
    | not in (val1, val2, ...) | 值不在列表中 | where product_id not in (501, 504) |
    | like pattern | 模式匹配 (% 任意多字符, _ 单字符) | where name like '张%' |
    | is null | 判断值是否为 NULL | where major is null |
    | is not null | 判断值是否不为 NULL | where email is not null |

  • where 子句独立示例:

    等于 (=): 查询专业是 '物理学' 的学生。

    select * from students where major = '物理学';
    
    AI 代码解读

    大于 (>): 查询价格超过 100 元的产品。

    select product_name, price from products where price > 100;
    
    AI 代码解读

    小于 (<): 查询 GPA 低于 3.0 的学生。

    select first_name, last_name, gpa from students where gpa < 3.0;
    
    AI 代码解读

    大于等于 (>=): 查询库存量至少为 50 的产品。

    select product_name, stock_quantity from products where stock_quantity >= 50;
    
    AI 代码解读

    小于等于 (<=): 查询价格不高于 500 元的产品。

    select product_name, price from products where price <= 500;
    
    AI 代码解读

    不等于 (!=<>): 查询专业不是 '化学' 的学生。

    select * from students where major != '化学';
    -- 或者
    -- select * from students where major <> '化学';
    
    AI 代码解读

    逻辑与 (and): 查询专业是 '计算机科学' 且 GPA 大于 3.5 的学生。

    select * from students where major = '计算机科学' and gpa > 3.5;
    
    AI 代码解读

    逻辑或 (or): 查询价格低于 100 元或者库存为 0 的产品。

    select * from products where price < 100 or stock_quantity = 0;
    
    AI 代码解读

    逻辑非 (not): 查询专业不是 '金融学' 的学生。

    select * from students where not major = '金融学';
    -- 注意:通常 `!=` 或 `<>` 更直观
    
    AI 代码解读

    范围 (between ... and ...): 查询价格在 100 元到 500 元之间的产品(包含边界)。

    select product_name, price from products where price between 100 and 500;
    
    AI 代码解读

    集合 (in (...)): 查询专业是 '物理学' 或 '化学' 的学生。

    select * from students where major in ('物理学', '化学');
    
    AI 代码解读

    集合否定 (not in (...)): 查询产品 ID 不是 501 或 504 的产品。

    select * from products where product_id not in (501, 504);
    
    AI 代码解读

    模糊匹配 (like %): 查询产品名称以 '笔记本' 开头的产品。

    select * from products where product_name like '笔记本%';
    
    AI 代码解读

    模糊匹配 (like %...%): 查询姓氏中包含 '三' 的学生。

    select * from students where last_name like '%三%';
    
    AI 代码解读

    模糊匹配 (like _): 查询名字刚好是两个字的学生(假设 first_name 存名字)。

    select * from students where first_name like '__';
    
    AI 代码解读

    空值判断 (is null): 查询没有填写专业的学生。

    select * from students where major is null;
    
    AI 代码解读

    非空判断 (is not null): 查询填写了邮箱的学生。

    select * from students where email is not null;
    
    AI 代码解读

3. 分组 (group by)

将具有相同值的行合并(分组)到单个汇总行中。通常与聚合函数一起使用。

  • 语法: ... group by column1, [column2, ...] ...
  • 规则: select 列表中未包含在聚合函数中的列,必须 出现在 group by 子句中。分组在 where 过滤之后进行。
  • 聚合函数 (常用): count(), sum(), avg(), max(), min()

示例:

-- 统计每个专业的学生人数
select major, count(*) as num_students
from students
where major is not null
group by major;

-- 计算每个专业学生的平均 GPA
select major, avg(gpa) as average_gpa
from students
group by major;
AI 代码解读

4. 分组过滤 (having)

group by 分组后的结果进行条件过滤。where 过滤行,having 过滤分组。 having 中通常包含聚合函数。

  • 语法: ... group by ... having condition_on_aggregate_results ...

示例:

-- 找出学生人数超过 1 人的专业
select major, count(*) as student_count
from students
group by major
having count(*) > 1;

-- 显示平均 GPA 大于 3.5 的专业
select major, avg(gpa) as avg_gpa
from students
group by major
having avg(gpa) > 3.5;
AI 代码解读

5. 列选择与处理 (select)

指定最终查询结果中要包含哪些列或表达式的值。

  • 语法: select [distinct] column1, column2, expression as alias, ...
  • 选项:
    • distinct: 去除最终结果集中的重复行。
    • 列别名 (as 或省略 as): 为列或表达式结果指定名称。
    • 可使用各种函数处理列。

示例:

select student_id as 学号, concat(first_name, ' ', last_name) as `学生全名`, gpa * 10 as scaled_gpa
from students;
AI 代码解读

6. 结果排序 (order by)

对最终的查询结果集进行排序。

  • 语法: ... order by column1 [asc | desc], column2 [asc | desc] ...;
  • 选项: asc (升序, 默认), desc (降序)。可按多列、列别名排序。

示例:

select major, avg(gpa) as avg_gpa
from students
group by major
order by avg_gpa desc; -- 按计算出的平均 GPA 降序
AI 代码解读

7. 限制返回行数 (limit)

限制最终结果集返回的行数。在排序之后执行。

  • 语法:
    • limit row_count
    • limit offset, row_count (跳过 offset 行)
    • limit row_count offset offset (同上)

示例:

select * from products order by price desc limit 5; -- 最贵的 5 个
select * from students order by gpa desc limit 10 offset 10; -- GPA 排名 11-20
AI 代码解读

!!! 查询逻辑执行顺序总结 !!!

  1. FROM: 确定源表(及 JOIN)。
  2. WHERE: 过滤行。
  3. GROUP BY: 分组。
  4. HAVING: 过滤分组。
  5. SELECT: 选择列/表达式,执行函数,应用 DISTINCT
  6. ORDER BY: 排序。
  7. LIMIT: 限制输出行数。

练习题

假设使用之前的 studentsproducts 表数据。

  1. 查询 students 表中所有 GPA 高于 3.7 的学生的姓名 (first_name, last_name) 和 GPA。
    答案:

    select first_name, last_name, gpa from students where gpa > 3.7;
    
    AI 代码解读
  2. 查询 products 表中所有产品名称包含 '键盘' 或 '鼠标' 的产品的名称和价格。
    答案:

    select product_name, price from products where product_name like '%键盘%' or product_name like '%鼠标%';
    
    AI 代码解读
  3. 查询 students 表中所有学生的完整姓名(拼接 first_namelast_name 并用空格隔开,列别名为 full_name)和他们的专业 (major)。
    答案:

    select concat(first_name, ' ', last_name) as full_name, major from students;
    
    AI 代码解读
  4. 查询 products 表中所有产品的名称和库存量,结果按库存量从高到低排序。
    答案:

    select product_name, stock_quantity from products order by stock_quantity desc;
    
    AI 代码解读
  5. 查询 students 表中 GPA 排名第 2 和第 3 的学生的学号和 GPA。(提示:使用 limitoffset
    答案:

    select student_id, gpa from students order by gpa desc limit 1, 2;
    -- 或者
    -- select student_id, gpa from students order by gpa desc limit 2 offset 1;
    
    AI 代码解读
  6. 查询 students 表中有多少个不同的专业?(列别名为 distinct_major_count)
    答案:

    select count(distinct major) as distinct_major_count from students where major is not null;
    
    AI 代码解读
  7. 查询 products 表中每种产品的总价值(价格 库存量),列别名为 total_value,并只显示总价值大于 10000 的产品名称和总价值。 答案:*

    -- 方法一: 在 where 中计算
    select product_name, (price * stock_quantity) as total_value
    from products
    where (price * stock_quantity) > 10000;
    
    AI 代码解读
  8. 查询 students 表中每个专业的学生人数,并且只显示学生人数大于等于 2 人的专业。
    答案:

    select major, count(*) as student_count
    from students
    where major is not null
    group by major
    having count(*) >= 2;
    
    AI 代码解读
  9. 查询 products 表中价格第二贵的产品信息。(提示:排序后使用 limit
    答案:

    select * from products order by price desc limit 1, 1;
    -- 或者
    -- select * from products order by price desc limit 1 offset 1;
    
    AI 代码解读
  10. 查询 students 表中姓氏为 '李' (last_name = '李') 或者名字里包含 '三' (first_name like '%三%') 的所有学生信息。
    答案:

select * from students where last_name = '李' or first_name like '%三%';
AI 代码解读
  1. 对于以下 SQL 查询语句:
select major, avg(gpa) as avg_gpa
from students
where enrollment_year > 2020
group by major
having count(*) >= 2
order by avg_gpa desc
limit 3;
AI 代码解读

请判断以下哪个操作最先被数据库执行?

A. 计算平均 GPA (avg(gpa))
B. 按 major 分组 (group by major)
C. 过滤入学年份 (where enrollment_year > 2020)
D. 按平均 GPA 排序 (order by avg_gpa desc)

答案: C. 过滤入学年份 (where enrollment_year > 2020)

解释: 根据 SQL 的逻辑执行顺序,WHERE 子句用于过滤原始表的行,是在 GROUP BYHAVINGSELECT(计算聚合函数)、ORDER BYLIMIT 之前执行的第一步筛选操作(在 FROM 之后)。

目录
打赏
0
1
2
0
1
分享
相关文章
数据控制语言 DCL
本篇文章详细介绍了 MySQL 中 DCL(数据控制语言)的核心命令,包括用户账户的创建、修改、删除 (CREATE USER, ALTER USER, DROP USER),以及数据库权限的授予与撤销 (GRANT, REVOKE)。文章通过清晰语法和实际示例,指导读者如何设置强密码、限制登录主机、精细授权数据库对象,帮助构建更安全可控的数据库系统。结合最佳实践与练习题,本教程适合 DBA 入门者和开发人员快速掌握 MySQL 权限管理能力。
100 1
2025 版 Java 学习路线实战指南从入门到精通
《Java学习路线实战指南(2025版)》是一份全面的Java开发学习手册,涵盖基础环境搭建、核心语法与新特性、数据结构与算法、微服务架构、云原生技术栈、AI融合及项目实战。内容包括JDK安装配置、IntelliJ IDEA设置、Records类与模式匹配增强、LeetCode题解、Spring Cloud微服务开发、Kubernetes部署、OpenAI API调用等。结合在线商城系统案例,采用Vue 3、Spring Boot 3.5、MySQL、Elasticsearch等技术,提供从理论到实践的完整路径,助力开发者掌握2025年最新趋势与最佳实践。
215 4
/var/log/syslog日志说明
`/var/log/syslog`是Unix和Linux的日志文件,记录系统事件和消息,由`syslogd`或`rsyslogd`生成。日志条目含时间戳、主机名、PID、日志级别(如DEBUG、ERROR)和事件描述。内容涵盖系统启动/关闭、硬件错误、网络、用户登录、安全事件等。查看日志可使用`cat`、`tail`、`less`或`grep`命令。不过,不同Linux发行版可能有变,如Ubuntu使用`journald`和`journalctl`。
1071 3
MySQL 常用函数
我们这次全面梳理 MySQL 中的常用函数,涵盖 聚合函数、字符串函数、日期时间函数、数学函数 和 控制流函数 等五大类。每类函数均配有语法说明与实用示例,帮助读者提升数据处理能力,如统计分析、文本处理、日期计算、条件判断等。文章结尾提供了丰富的实战练习,帮助读者巩固和应用函数技巧,是进阶 SQL 编程与数据分析的实用工具手册。
140 2
通义灵码用户说 | 编程智能体+MCP加持,秒查附近蜜雪冰城
通义灵码现已全面支持Qwen3,新增智能体模式,具备自主决策、环境感知、工具使用等能力,可端到端完成编码任务。支持问答、文件编辑、智能体多模式自由切换,结合MCP工具与记忆功能,提升开发效率。AI IDE重构编程流程,让开发更智能高效。
336 20
收到阿里云【乘风者计划】博主证书和奖励
收到阿里云【乘风者计划】博主证书和奖励 2023年2月对我来说是一个很好的开端,因为我在1号就收到了阿里云寄给我的【乘风者计划】博主证书和奖励。好兆头啊! 我收到的是我获得的【技术博主】【星级博主】【专家博主】三个的奖品和证书,一快给我寄过来哒!
2978 2
收到阿里云【乘风者计划】博主证书和奖励
《告别传统苦码,飞算JavaAI自然语言“译”出企业级代码》
飞算JavaAI是一款革命性企业级应用开发工具,通过自然语言交互精准理解需求,自动生成高质量代码与设计,大幅缩短开发周期、提升效率。它突破传统Java开发繁琐流程与沟通壁垒,降低技术门槛,让开发者聚焦创新,助力企业敏捷响应市场变化并优化资源投入。同时,它推动人才培养与跨领域合作,促进数字化转型,为企业带来更高竞争力与价值。
114 25
《解锁JNA与CUDA内核密码,定制专属AI算子》
JNA(Java Native Access)让Java程序轻松调用本地代码,无需复杂JNI操作,动态加载本地库并自动映射Java与C/C++语言。结合CUDA(NVIDIA并行计算平台),可高效开发自定义AI算子。CUDA内核通过分解任务充分利用GPU多核优势,满足AI算法中矩阵运算和数据处理需求。两者结合虽面临性能优化与跨平台兼容性挑战,但能充分发挥Java便捷性与CUDA高性能,为AI领域提供强大支持。
74 27
MySQL 5.6/5.7 DDL 失败残留文件清理指南
通过本文的指南,您可以更安全地处理 MySQL 5.6 和 5.7 版本中 DDL 失败后的残留文件,有效避免数据丢失和数据库不一致的问题。
拯救海量数据:PostgreSQL分区表性能优化实战手册(附压测对比)
本文深入解析PostgreSQL分区表的核心原理与优化策略,涵盖性能痛点、实战案例及压测对比。首先阐述分区表作为继承表+路由规则的逻辑封装,分析分区裁剪失效、全局索引膨胀和VACUUM堆积三大性能杀手,并通过电商订单表崩溃事件说明旧分区维护的重要性。接着提出四维设计法优化分区策略,包括时间范围分区黄金法则与自动化维护体系。同时对比局部索引与全局索引性能,展示后者在特定场景下的优势。进一步探讨并行查询优化、冷热数据分层存储及故障复盘,解决分区锁竞争问题。
149 2

数据库

+关注
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等