当前位置:首页 > 技术 > 正文内容

MySQL单表查询语句结构详解

访客 技术 2026年5月25日 3

基础查询语法

在MySQL中,数据存储于具有特定结构的表内,用户可通过SQL语句实现增删改查操作。最基本的查询方式如下:

  • SELECT * FROM 表名;:检索指定表中所有字段的全部记录。
  • SELECT 字段1, 字段2 FROM 表名;:仅获取指定字段的数据。

查询子句及其执行顺序

完整的单表查询可包含多个子句,各关键字按以下逻辑顺序排列(但并非全部必须):

  1. WHERE:对原始数据进行条件过滤(分组前筛选)。
  2. GROUP BY:根据某一列或多列将数据分组。
  3. HAVING:对已分组的结果再次筛选(分组后条件判断)。
  4. DISTINCT:去除重复的字段组合。
  5. ORDER BY:对最终结果集排序。
  6. LIMIT:限制返回的行数,常用于分页。

此外,还支持正则匹配和字符串拼接函数增强查询表达能力。

示例数据准备

为演示各项功能,创建并填充角色信息表:

CREATE TABLE role_info (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    gender ENUM('male', 'female') DEFAULT 'male',
    age TINYINT UNSIGNED DEFAULT 28,
    birth DATE NOT NULL,
    game_title VARCHAR(50),
    price DECIMAL(15,2),
    studio_room INT,
    team_id INT
);

INSERT INTO role_info (name, gender, age, birth, game_title, price, studio_room, team_id) VALUES
('蔚', 'female', 18, '2017-03-01', 'LOL', 7300.33, 401, 1),
('金克斯', 'female', 16, '2015-03-02', 'LOL', 1000000.31, 401, 1),
('杰斯', 'male', 27, '2013-03-05', 'LOL', 8300.00, 401, 1),
('维克多', 'male', 22, '2014-07-01', 'LOL', 3500.00, 401, 1),
('凯特琳', 'female', 17, '2012-11-01', 'LOL', 2100.00, 401, 1),
('希尔克', 'male', 50, '2011-02-11', 'LOL', 9000.00, 401, 1),
('范德尔', 'male', 60, '1900-03-01', 'LOL', 30000.00, 401, 1),
('亚瑟', 'male', 48, '2010-11-11', 'HOK', 10000.00, 402, 1),
('艾琳', 'female', 48, '2015-03-11', 'HOK', 3000.13, 402, 2),
('云缨', 'female', 38, '2010-11-01', 'HOK', 2000.35, 402, 2),
('东方曜', 'male', 18, '2011-03-12', 'HOK', 1000.37, 402, 2),
('宫本武藏', 'male', 18, '2016-05-13', 'HOK', 3000.29, 402, 2),
('司空震', 'male', 28, '2017-01-27', 'HOK', 4000.33, 402, 2),
('巴巴托斯', 'male', 28, '2016-03-11', 'GI', 10000.13, 403, 3),
('摩拉克斯', 'male', 18, '1997-03-12', 'GI', 20000.00, 403, 3),
('巴尔泽布', 'female', 18, '2013-03-11', 'GI', 19000.00, 403, 3),
('布耶尔', 'male', 18, '2015-04-11', 'GI', 18000.00, 403, 3),
('天理', 'female', 18, '2014-05-12', 'GI', 17000.00, 403, 3);

WHERE 条件过滤

用于在分组或排序前对原始记录施加筛选条件。

范围匹配:BETWEEN ... AND

-- 查询ID介于3到6之间的角色
SELECT * FROM role_info WHERE id BETWEEN 3 AND 6;

集合匹配:IN 与 NOT IN

-- 查找价格为17000、18000或20000的角色
SELECT * FROM role_info WHERE price IN (17000, 18000, 20000);

-- 排除某些值
SELECT * FROM role_info WHERE price NOT IN (30000, 1000);

模糊匹配:LIKE

使用通配符进行模式匹配:

  • %:匹配任意长度字符(包括零个)。
  • _:匹配单个字符。
-- 名称以"巴"开头
SELECT name, price FROM role_info WHERE name LIKE '巴%';

-- 名称为四个汉字
SELECT name, price FROM role_info WHERE name LIKE '____';

存在性判断:EXISTS

仅当子查询返回结果时,主查询才执行。

SELECT name, age FROM role_info r1 
WHERE EXISTS (SELECT 1 FROM role_info r2 WHERE r2.name = '东方曜');

GROUP BY 数据分组

将数据按某一字段归类,便于分析群体特征。

-- 按游戏名称分组
SELECT game_title, COUNT(*) AS total_roles FROM role_info GROUP BY game_title;

ONLY_FULL_GROUP_BY 模式说明

启用该SQL模式后,SELECT列表中只能出现分组字段或聚合函数计算值,防止非确定性输出。可在配置文件中设置:

sql_mode='STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,ONLY_FULL_GROUP_BY'

常用聚合函数

函数用途
MAX()最大值
MIN()最小值
AVG()平均值
SUM()总和
COUNT()计数
GROUP_CONCAT()合并组内字段为字符串
-- 各游戏中最贵角色的价格
SELECT game_title, MAX(price) AS max_price FROM role_info GROUP BY game_title;

-- 列出每款游戏的所有角色名
SELECT game_title, GROUP_CONCAT(name SEPARATOR ', ') AS characters FROM role_info GROUP BY game_title;

HAVING 分组后筛选

针对聚合后的结果设定条件,不能使用WHERE替代。

-- 统计各游戏中年龄大于20的角色平均价格,并保留高于1万元的组
SELECT game_title, AVG(price) AS avg_price 
FROM role_info 
WHERE age > 20 
GROUP BY game_title 
HAVING AVG(price) > 10000 
ORDER BY avg_price DESC;

DISTINCT 去重处理

消除重复的字段组合记录。

-- 查询不同的性别与工作室组合
SELECT DISTINCT gender, studio_room FROM role_info;

-- 统计不同价格数量
SELECT COUNT(DISTINCT price) FROM role_info;

ORDER BY 结果排序

控制最终输出顺序,支持多级排序。

-- 年龄升序,相同年龄下价格降序
SELECT * FROM role_info ORDER BY age ASC, price DESC;

-- 对分组结果排序
SELECT game_title, AVG(age) AS avg_age 
FROM role_info 
GROUP BY game_title 
ORDER BY avg_age DESC;

LIMIT 实现分页

控制返回行数,适用于大数据量场景。

-- 获取前5条记录
SELECT * FROM role_info LIMIT 5;

-- 跳过前5条,取接下来的6条(分页第二页)
SELECT * FROM role_info LIMIT 5, 6;

REGEXP 正则表达式匹配

提供比LIKE更强大的文本匹配能力。

-- 名字以"巴"或"金"开头,且以"斯"或"布"结尾
SELECT * FROM role_info WHERE name REGEXP '^[巴金].*[斯布]$';

字符串拼接:CONCAT 与 CONCAT_WS

构造复合字段输出。

-- 使用自定义连接符拼接字段
SELECT CONCAT(game_title, ' - ', name) AS full_desc FROM role_info ORDER BY age DESC LIMIT 5;

-- 使用统一分隔符连接多个字段
SELECT CONCAT_WS(' | ', game_title, name, price) AS detail_line FROM role_info ORDER BY price DESC LIMIT 5;

综合练习题

  1. 统计男女角色各自的平均售价:
    SELECT gender, AVG(price) AS avg_price FROM role_info GROUP BY gender;
  2. 计算年龄在18至20岁之间(含边界)的角色总价,按游戏分类:
    SELECT game_title, SUM(price) AS total_price 
    FROM role_info 
    WHERE age BETWEEN 18 AND 20 
    GROUP BY game_title;
标签: MySQL

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。