MySQL高阶查询语句与视图实战指南
MySQL高阶查询语句与视图实战指南
文章目录
- MySQL高阶查询语句与视图实战指南
- 一、常用高阶查询技巧
- 1. 按关键字排序(ORDER BY)
- 基础用法
- 进阶用法:多字段排序+条件过滤
- 2. 区间判断与去重(AND/OR + DISTINCT)
- 区间判断:AND/OR
- 去重查询:DISTINCT
- 3. 结果分组(GROUP BY + 聚合函数)
- 基础分组
- 进阶分组:条件筛选+排序
- 4. 限制结果条数(LIMIT)
- 常用场景
- 5. 简化查询:设置别名(AS)
- 字段别名
- 表别名
- 特殊用法:用别名创建表
- 6. 模糊查询(通配符 + LIKE)
- 常用案例
- 7. 嵌套查询(子查询)
- 基础用法:IN关键字
- 进阶用法:子查询在INSERT/UPDATE/DELETE中
- 特殊用法:EXISTS关键字
- 8. NULL值处理
- 常用操作
- 二、视图:简化查询+数据安全
- 1. 什么是视图?
- 2. 视图的作用
- 3. 视图与表的区别和联系
- 4. 视图实战案例
- 案例1:单表创建视图
- 案例2:多表创建视图
- 案例3:通过视图修改原表
- 5. 视图的注意事项
- 三、总结
在日常的数据库操作中,基础的增删改查(CRUD)往往无法满足复杂的业务需求。比如需要对查询结果排序、筛选特定区间数据、简化多表查询,或者控制数据访问权限等。今天这篇文章,就带大家深入学习MySQL的高阶查询语句和视图的应用,结合实际案例,让你轻松应对复杂场景。
一、常用高阶查询技巧
首先,我们先搭建一个测试环境,创建一张info
表并插入学生数据,后续案例都会基于这张表展开:
-- 创建info表
create table info (id int,name varchar(10) primary key not null,score decimal(5,2),address varchar(20),hobbid int(5)
);-- 插入测试数据
insert into info values
(1,'liuyi',80,'beijing',2),
(2,'wangwu',90,'shengzheng',2),
(3,'lisi',60,'shanghai',4),
(4,'tianqi',99,'hangzhou',5),
(5,'jiaoshou',98,'laowo',3),
(6,'hanmeimei',10,'nanjing',3),
(7,'lilei',11,'nanjing',5);
1. 按关键字排序(ORDER BY)
类比Windows任务管理器的排序功能,ORDER BY
可以对查询结果按单个或多个字段排序,默认升序(ASC
),降序需显式指定(DESC
)。
基础用法
- 按分数升序排列(默认
ASC
,可省略):
select id,name,score from info order by score;
- 按分数降序排列:
select id,name,score from info order by score desc;
进阶用法:多字段排序+条件过滤
当第一个排序字段值相同时,会按第二个字段排序;还可结合WHERE
筛选数据。比如筛选地址为“杭州”的学生,按分数降序排列:
select name,score from info where address='hangzhou' order by score desc;
再比如,先按兴趣ID(hobbid
)降序,相同兴趣的学生按ID升序排列:
select id,name,hobbid from info order by hobbid desc, id;
2. 区间判断与去重(AND/OR + DISTINCT)
区间判断:AND/OR
- 筛选分数大于70且小于等于90的学生:
select * from info where score >70 and score <=90;
- 筛选分数大于70或小于等于90的学生(注意:逻辑或会包含大部分数据,需谨慎使用):
select * from info where score >70 or score <=90;
- 多条件嵌套:筛选分数大于70,或分数在75-90之间的学生:
select * from info where score >70 or (score >75 and score <90);
去重查询:DISTINCT
当某个字段存在重复值时,用DISTINCT
只保留唯一值。比如查询所有不重复的兴趣ID:
select distinct hobbid from info;
3. 结果分组(GROUP BY + 聚合函数)
GROUP BY
通常与聚合函数搭配使用,常用聚合函数有:
COUNT()
:计数SUM()
:求和AVG()
:求平均MAX()
/MIN()
:求最大/最小值
基础分组
按hobbid
分组,统计每个兴趣的学生人数:
select count(name) as student_count, hobbid from info group by hobbid;
进阶分组:条件筛选+排序
筛选分数大于等于80的学生,按hobbid
分组,再按学生人数升序排列:
select count(name) as student_count, hobbid from info where score>=80 group by hobbid order by student_count asc;
4. 限制结果条数(LIMIT)
LIMIT
是高频使用的语句,用于只返回部分结果,语法为:
SELECT 字段 FROM 表名 LIMIT [偏移量,] 条数;
- 偏移量可选,默认从第0行开始(即第一条数据);
- 条数:要返回的记录数。
常用场景
- 显示前3条数据:
select * from info limit 3;
- 从第4行开始(偏移量为3),显示3条数据:
select * from info limit 3,3;
- 按ID降序,显示最后3条数据(常用于获取最新数据):
select id,name from info order by id desc limit 3;
5. 简化查询:设置别名(AS)
当表名或字段名较长时,用AS
设置别名(AS
可省略),增强SQL可读性。
字段别名
将name
改为“姓名”,score
改为“成绩”:
select name as 姓名, score as 成绩 from info;
表别名
查询时给表设置别名,简化多表查询(后续视图会用到):
select i.name as 姓名, i.score as 成绩 from info as i;
特殊用法:用别名创建表
将info
表的查询结果作为新表t1
的结构和数据(注意:原表的主键约束可能无法完全复制):
create table t1 as select * from info;
6. 模糊查询(通配符 + LIKE)
通配符用于匹配部分字符,常与LIKE
搭配,常用通配符:
%
:匹配0个、1个或多个字符;_
:匹配单个字符。
常用案例
- 查询名字以“c”开头的学生:
select id,name from info where name like 'c%';
- 查询名字中包含“g”的学生:
select id,name from info where name like '%g%';
- 查询名字格式为“c_ic_i”的学生(比如“caicai”):
select id,name from info where name like 'c_ic_i';
7. 嵌套查询(子查询)
子查询(内查询)是嵌套在主查询中的SQL语句,先执行子查询,结果作为主查询的条件。
基础用法:IN关键字
查询分数大于80的学生姓名和成绩(子查询先获取符合条件的ID,主查询根据ID筛选数据):
select name,score from info where id in (select id from info where score>80);
进阶用法:子查询在INSERT/UPDATE/DELETE中
- 插入数据:将
info
表中ID在ky11
表中的记录插入t1
:
insert into t1 select * from info where id in (select * from ky11);
- 更新数据:将
ky11
表中ID=2对应的学生分数改为50:
update info set score=50 where id in (select * from ky11 where id=2);
- 删除数据:删除分数大于80的学生:
delete from info where id in (select id from info where score>80);
特殊用法:EXISTS关键字
EXISTS
判断子查询结果是否为空,不为空则返回TRUE
,否则FALSE
。比如判断是否存在分数等于80的学生,若存在则统计info
表总记录数:
select count(*) from info where exists(select id from info where score=80);
8. NULL值处理
NULL
表示“缺失值”,与0、空字符串(''
)不同:
- 空字符串长度为0,不占空间;
NULL
长度未知,占用空间;COUNT()
会忽略NULL
,但包含空字符串。
常用操作
- 查询
addr
字段为NULL
的记录:
select * from info where addr is NULL;
- 查询
addr
字段不为NULL
的记录:
select * from info where addr is not null;
二、视图:简化查询+数据安全
1. 什么是视图?
视图是数据库中的虚拟表,不存储真实数据,只保存对真实表的查询逻辑(类似“镜子”,动态映射真实数据)。
2. 视图的作用
- 简化查询:将复杂的多表查询封装为视图,后续直接查询视图即可;
- 数据安全:给不同用户提供不同视图,隐藏敏感字段(比如不给普通用户看学生的身份证号);
- 灵活适配:同一批真实数据,可根据需求生成多个视图。
3. 视图与表的区别和联系
维度 | 视图(View) | 表(Table) |
---|---|---|
数据存储 | 不存储真实数据,只存查询逻辑 | 存储真实物理数据 |
编译状态 | 已编译的SQL语句 | 未编译,动态执行 |
空间占用 | 不占物理空间 | 占用物理空间 |
安全性 | 可隐藏表结构,权限更精细 | 直接暴露表结构 |
修改影响 | 修改视图可能影响原表 | 修改表直接影响数据 |
联系:视图基于表存在,一个视图可对应一个或多个表;视图的结构和数据来自表。
4. 视图实战案例
案例1:单表创建视图
创建一个视图,只显示分数大于等于80的学生(后续原表数据更新,视图会同步变化):
-- 创建视图
create view v_score as select * from info where score>=80;-- 查询视图
select * from v_score;
案例2:多表创建视图
先创建test01
表存储学生年龄:
create table test01 (id int,name varchar(10),age char(10));
insert into test01 values(1,'zhangsan',20),(2,'lisi',30),(3,'wangwu',29);
创建视图,关联info
和test01
,显示学生ID、姓名、分数和年龄:
create view v_info(id,name,score,age) as
select info.id,info.name,info.score,test01.age
from info,test01
where info.name=test01.name;-- 查询视图
select * from v_info;
案例3:通过视图修改原表
视图不仅能查,还能修改原表数据(前提是视图字段对应原表字段,无函数计算)。比如修改v_score
视图中“tianqi”的分数为120:
update v_score set score='120' where name='tianqi';-- 验证原表数据
select * from info where name='tianqi';
5. 视图的注意事项
- 不建议用视图做增删改:复杂视图(如多表关联、含聚合函数)无法增删改,容易报错;
- 视图不保存数据:查询视图时,本质是执行底层SQL,性能取决于原表索引;
- 删除视图不影响原表:
drop view v_score;
只会删除视图,不会删除原表数据。
三、总结
本文介绍的MySQL高阶功能,覆盖了日常开发中90%以上的复杂查询场景:
- 排序与筛选:
ORDER BY + WHERE
实现精准排序; - 分组统计:
GROUP BY + 聚合函数
搞定数据汇总; - 简化操作:
LIMIT
限制结果、AS
设置别名、DISTINCT
去重; - 复杂查询:子查询解决嵌套逻辑,视图封装多表关联;
- 细节处理:
NULL
值判断、通配符模糊查询。
这些技巧需要结合实际业务多练,比如用视图封装报表查询、用子查询筛选复杂条件,慢慢就能熟练掌握。如果有疑问,欢迎在评论区交流!