FORMA

查询数据

查询数据(DQL - SELECT)

数据查询语言(DQL)用于从数据库中检索数据,核心是 SELECT 语句。下面从基础查询、条件筛选、排序、限制行数、聚合与分组等方面进行介绍。

一、基础查询

sql
-- 查询所有列
SELECT * FROM table_name;

-- 查询指定列
SELECT column1, column2 FROM table_name;

-- 查询并去重
SELECT DISTINCT column1 FROM table_name;

说明

  • * 表示返回所有列,但在生产环境中建议列出具体列名,减少网络传输并提高可读性。
  • DISTINCT 用于去除查询结果中重复的行(作用于所有选中的列)。

示例

sql
-- 查看学生表所有信息
SELECT * FROM students;

-- 只查询姓名和年龄
SELECT name, age FROM students;

-- 查询有哪些不同的班级编号
SELECT DISTINCT class_id FROM students;

二、带条件查询(WHERE)

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

sql
SELECT column1, column2
FROM table_name
WHERE condition;

常用条件运算符

类型运算符示例
比较=, <>(或 !=), >, <, >=, <=age >= 18
逻辑AND, OR, NOTage >= 18 AND city = 'Beijing'
范围BETWEEN ... AND ...score BETWEEN 60 AND 100
集合IN (value1, value2, ...)class_id IN (101, 102)
模糊匹配LIKE% 任意多个字符,_ 单个字符)name LIKE '张%'
空值判断IS NULL, IS NOT NULLemail IS NULL

示例

sql
-- 查询年龄大于20的学生
SELECT * FROM students WHERE age > 20;

-- 查询班级为101或102,且成绩及格的学生
SELECT * FROM students
WHERE class_id IN (101, 102) AND score >= 60;

-- 查询姓“李”且名字只有两个字的同学
SELECT * FROM students WHERE name LIKE '李_';

-- 查询手机号未填写的用户
SELECT * FROM users WHERE phone IS NULL;

三、排序(ORDER BY)

ORDER BY 用于对结果集进行排序,默认为升序(ASC),可指定降序(DESC)。

sql
SELECT column_list
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;

规则

  • 先按第一列排序,若相同再按第二列,依此类推。
  • 空值(NULL)在排序中通常视为最小值(具体取决于数据库实现,MySQL 中默认 NULL 最小)。

示例

sql
-- 按年龄升序(从小到大)
SELECT name, age FROM students ORDER BY age;

-- 按成绩降序(从高到低),成绩相同则按姓名升序
SELECT name, score FROM students
ORDER BY score DESC, name ASC;

四、限制结果行数(LIMIT)

LIMIT 用于限制返回的行数,常用于分页查询。

sql
-- 返回前 N 行
SELECT * FROM table_name LIMIT N;

-- 跳过 offset 行,返回 count 行
SELECT * FROM table_name LIMIT offset, count;

替代语法(MySQL 也支持):

sql
SELECT * FROM table_name LIMIT count OFFSET offset;

示例

sql
-- 查询前10名学生
SELECT * FROM students LIMIT 10;

-- 分页:每页10条,查看第3页(跳过前20条,取10条)
SELECT * FROM students LIMIT 20, 10;

注意LIMIT 通常与 ORDER BY 配合使用,否则结果顺序不确定,分页可能重复或遗漏。

五、聚合函数与分组(GROUP BY)

聚合函数对一组值进行计算并返回单个值。常与 GROUP BY 一起使用,按某个字段分组后分别计算。

常用聚合函数

函数说明
COUNT(*)统计行数
COUNT(column)统计某列非空值的个数
SUM(column)求和
AVG(column)平均值
MAX(column)最大值
MIN(column)最小值

分组查询

sql
SELECT group_column, aggregate_function(column)
FROM table_name
[WHERE condition]
GROUP BY group_column
[HAVING group_condition];
  • GROUP BY 将数据划分为若干组,每一组返回一条结果。
  • HAVING 用于对分组后的结果进行筛选(类似于 WHERE,但作用在组上)。

示例

sql
-- 统计每个班级的学生人数
SELECT class_id, COUNT(*) AS student_count
FROM students
GROUP BY class_id;

-- 计算每个班级的平均成绩,并只显示平均分大于80的班级
SELECT class_id, AVG(score) AS avg_score
FROM students
GROUP BY class_id
HAVING AVG(score) > 80;

-- 统计每个班级男女学生各自的人数
SELECT class_id, gender, COUNT(*)
FROM students
GROUP BY class_id, gender;

重要区别

  • WHERE 在分组前过滤行,HAVING 在分组后过滤组。
  • 使用 GROUP BY 后,SELECT 中出现的非聚合列必须出现在 GROUP BY 子句中(或依赖于分组列)。

六、完整查询语法顺序

一个完整的 SELECT 语句顺序如下(按书写顺序):

sql
SELECT   [DISTINCT] select_list
FROM       table_references
[WHERE     condition]
[GROUP BY  group_columns]
[HAVING    group_condition]
[ORDER BY  sort_columns]
[LIMIT     {[offset,] row_count | row_count OFFSET offset}];

执行逻辑顺序(数据库内部执行顺序略有不同,但可理解为):

  1. FROM 找到表
  2. WHERE 筛选行
  3. GROUP BY 分组
  4. HAVING 筛选组
  5. SELECT 计算列
  6. ORDER BY 排序
  7. LIMIT 限制行数

七、综合示例

sql
-- 查询学生表:按班级分组,统计每班平均年龄,只显示平均年龄小于25的班级,按平均年龄降序,取前2名
SELECT
    class_id,
    AVG(age) AS avg_age,
    COUNT(*) AS num
FROM students
WHERE status = 'active'
GROUP BY class_id
HAVING AVG(age) < 25
ORDER BY avg_age DESC
LIMIT 2;

通过上述查询,我们可以灵活地从数据库中提取需要的信息。掌握 SELECT 的基本用法是成为数据库开发高手的第一步。

参考文献

资料说明
MySQL 8.0 手册官方
数据存储导读学习路径

Series

mysql

7 / 11