数据查询语言 DQL

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 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. 限制输出行数

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

前提: 操作前需使用 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;

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 = '物理学';
    

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

    select product_name, price from products where price > 100;
    

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

    select first_name, last_name, gpa from students where gpa < 3.0;
    

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

    select product_name, stock_quantity from products where stock_quantity >= 50;
    

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

    select product_name, price from products where price <= 500;
    

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

    select * from students where major != '化学';
    -- 或者
    -- select * from students where major <> '化学';
    

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

    select * from students where major = '计算机科学' and gpa > 3.5;
    

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

    select * from products where price < 100 or stock_quantity = 0;
    

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

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

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

    select product_name, price from products where price between 100 and 500;
    

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

    select * from students where major in ('物理学', '化学');
    

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

    select * from products where product_id not in (501, 504);
    

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

    select * from products where product_name like '笔记本%';
    

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

    select * from students where last_name like '%三%';
    

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

    select * from students where first_name like '__';
    

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

    select * from students where major is null;
    

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

    select * from students where email is not null;
    

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;

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;

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;

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 降序

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

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

  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;
    
  2. 查询 products 表中所有产品名称包含 '键盘' 或 '鼠标' 的产品的名称和价格。
    答案:

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

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

    select product_name, stock_quantity from products order by stock_quantity desc;
    
  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;
    
  6. 查询 students 表中有多少个不同的专业?(列别名为 distinct_major_count)
    答案:

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

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

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

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

select * from students where last_name = '李' or first_name like '%三%';
  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;

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

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 之后)。

目录
相关文章
|
安全 Ubuntu Unix
/var/log/syslog日志说明
`/var/log/syslog`是Unix和Linux的日志文件,记录系统事件和消息,由`syslogd`或`rsyslogd`生成。日志条目含时间戳、主机名、PID、日志级别(如DEBUG、ERROR)和事件描述。内容涵盖系统启动/关闭、硬件错误、网络、用户登录、安全事件等。查看日志可使用`cat`、`tail`、`less`或`grep`命令。不过,不同Linux发行版可能有变,如Ubuntu使用`journald`和`journalctl`。
1574 3
|
云栖大会 开发者
收到阿里云【乘风者计划】博主证书和奖励
收到阿里云【乘风者计划】博主证书和奖励 2023年2月对我来说是一个很好的开端,因为我在1号就收到了阿里云寄给我的【乘风者计划】博主证书和奖励。好兆头啊! 我收到的是我获得的【技术博主】【星级博主】【专家博主】三个的奖品和证书,一快给我寄过来哒!
3185 2
收到阿里云【乘风者计划】博主证书和奖励
|
9月前
|
SQL 关系型数据库 MySQL
数据控制语言 DCL
本篇文章详细介绍了 MySQL 中 DCL(数据控制语言)的核心命令,包括用户账户的创建、修改、删除 (CREATE USER, ALTER USER, DROP USER),以及数据库权限的授予与撤销 (GRANT, REVOKE)。文章通过清晰语法和实际示例,指导读者如何设置强密码、限制登录主机、精细授权数据库对象,帮助构建更安全可控的数据库系统。结合最佳实践与练习题,本教程适合 DBA 入门者和开发人员快速掌握 MySQL 权限管理能力。
356 1
|
6月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
711 1
二、Linux文本处理与文件操作核心命令
|
9月前
|
消息中间件 Java 微服务
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年最新趋势与最佳实践。
678 4
|
6月前
|
存储 安全 Linux
三、Linux用户与权限管理详解
管理Linux系统就像当一个大楼的管家。首先,你得用useradd和passwd给新员工发“钥匙”(创建用户并设密码),并用groupadd把他们分到不同“部门”(用户组)。然后,你要为每个“房间”(文件或目录)设定规矩,这就是文件权限:用chmod命令设置谁(所有者、同部门、其他人)可以“进入”(x)、“读取”(r)或“写入”(w)。最后,用chown还能把房间的归属权转让给别人。
675 5
|
6月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1052 58
|
9月前
|
JSON 自然语言处理 Linux
linux命令—tree
tree是一款强大的Linux命令行工具,用于以树状结构递归展示目录和文件,直观呈现层级关系。支持多种功能,如过滤、排序、权限显示及格式化输出等。安装方法因系统而异常用场景包括:基础用法(显示当前或指定目录结构)、核心参数应用(如层级控制-L、隐藏文件显示-a、完整路径输出-f)以及进阶操作(如磁盘空间分析--du、结合grep过滤内容、生成JSON格式列表-J等)。此外,还可生成网站目录结构图并导出为HTML文件。注意事项:使用Tab键补全路径避免错误;超大目录建议限制遍历层数;脚本中推荐禁用统计信息以优化性能。更多详情可查阅手册mantree。
788 143
linux命令—tree
|
9月前
|
SQL 关系型数据库 MySQL
MySQL 5.6/5.7 DDL 失败残留文件清理指南
通过本文的指南,您可以更安全地处理 MySQL 5.6 和 5.7 版本中 DDL 失败后的残留文件,有效避免数据丢失和数据库不一致的问题。
|
9月前
|
机器学习/深度学习 计算机视觉 索引
眨眼张嘴人脸识别软件,图片眨眼摇头生成器,制作眨眼睛张嘴图软件
本系统基于OpenCV和Dlib实现人脸动态特征识别与图像生成,包含眨眼、张嘴检测及头部姿态估计功能,提供约200行核心代码,并支持扩展深度学习模型提升性能。