千家信息网

MySQL中逻辑查询的示例分析

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍了MySQL中逻辑查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在MySQL中,查询是用于构建DELET
千家信息网最后更新 2026年10月31日MySQL中逻辑查询的示例分析

这篇文章主要介绍了MySQL中逻辑查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

在MySQL中,查询是用于构建DELETE、UPDATE的基础,因为你要删除或者更新他们时,首先就是要查出这些记录,所以SELECT显的尤为重要,对于查询处理,可以分为逻辑查询和物理查询,逻辑查询表示执行SELECT语句时应该产生什么样的结果,而物理查询表示MySQL如何得到这个结果的。

本章来说一下逻辑查询。

在SQL语句中,最先处理的就是FROM语句,最后执行的是LIMIT语句,如果把所有的语句都用上,如GROUP BY、ORDER BY,那么大致可以分为10个步骤,如下所示,每个操作都会产生一张虚拟表。

(7) select (8)distinct(1) from (3)  join (2)    on<条件>(4) where <条件>(5) group by<字段list>(6) having<条件>(9) order by<字段>(10) limit

下面通过一个实际例子来分析一下,首先创建两张表,用户和订单。

mysql> create table user (userId int(11),userName varchar(255),city varchar(255), primary key (userId));Query OK, 0 rows affected, 1 warning (0.05 sec)mysql> create table orders(orderId int(11) ,userId int(11) ,primary key (orderId));Query OK, 0 rows affected, 2 warnings (0.05 sec)

插入数据。

insert user values(1,"张三","内蒙");insert user values(2,"李四","内蒙");insert user values(3,"王五","北京");insert user values(4,"迪迦","西藏");insert user values(5,"金甲战士","内蒙");insert orders values(10001,1);insert orders values(10002,1);insert orders values(10003,4);insert orders values(10004,1);insert orders values(10005,1);insert orders values(10006,4);insert orders values(10007,2);

好,现在来查询一下来自内蒙,且订单数量小于3的用户,SQL如下。

mysql> select userName,count(orders.orderId) as total from user left join orders on user.userId = orders.userId where city="内蒙" group by user.userId having count(orders.orderId)<3 order by total desc;+--------------+-------+| userName     | total |+--------------+-------+| 李四         |     1 || 金甲战士     |     0 |+--------------+-------+2 rows in set (0.00 sec)

有数据有SQL,下面分析一下具体流程。

1. 笛卡尔乘积

首先要做的是对FROM语句前后的两张表进行笛卡尔乘积,那么什么是笛卡尔乘积?举个例子来说,假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

所以,对应上面的数据,最终会产生一张虚拟表VT1,他将包含35行数据,具体数据如下所示。

userIduserNamecityorderIduserId
1张三内蒙100011
1张三内蒙100021
1张三内蒙100034
1张三内蒙100051
1张三内蒙100061
1张三内蒙100054
1张三内蒙100072
..................



5金甲战士内蒙100011
5金甲战士内蒙100021

2. ON过滤器

下一步,通过ON后面的添加过滤掉不需要的数据,在上述SQL中,条件是user.userId = orders.userId ,所以通过上面生成的虚拟表VT1,除去不相关的数据,生成新的虚拟表VT2,最终的结果如下。

+--------+--------------+--------+---------+--------+| userId | userName     | city   | orderId | userId |+--------+--------------+--------+---------+--------+|      1 | 张三         | 内蒙   |   10005 |      1 ||      1 | 张三         | 内蒙   |   10004 |      1 ||      1 | 张三         | 内蒙   |   10002 |      1 ||      1 | 张三         | 内蒙   |   10001 |      1 ||      2 | 李四         | 内蒙   |   10007 |      2 ||      3 | 王五         | 北京   |    NULL |   NULL ||      4 | 迪迦         | 西藏   |   10006 |      4 ||      4 | 迪迦         | 西藏   |   10003 |      4 ||      5 | 金甲战士     | 内蒙   |    NULL |   NULL |+--------+--------------+--------+---------+--------+

3.添加外部行

这一步只有在连接类型为OUTER JOIN才发生。

LEFT OUTER JOIN把左表记为保留表,RIGHT OUTER JOIN把右表作为保留表,FULL OUTER JOIN表示都作为保留表,添加外部行的工作就是在上一步的基础上添加保留表中被过滤条件过滤掉的数据,非保留表的数据被赋值NULL。

最终生成下面的结果,记为虚拟表VT3。

+--------+--------------+--------+---------+--------+| userId | userName     | city   | orderId | userId |+--------+--------------+--------+---------+--------+|      1 | 张三         | 内蒙   |   10005 |      1 ||      1 | 张三         | 内蒙   |   10004 |      1 ||      1 | 张三         | 内蒙   |   10002 |      1 ||      1 | 张三         | 内蒙   |   10001 |      1 ||      2 | 李四         | 内蒙   |   10007 |      2 ||      3 | 王五         | 北京   |    NULL |   NULL ||      4 | 迪迦         | 西藏   |   10006 |      4 ||      4 | 迪迦         | 西藏   |   10003 |      4 ||      5 | 金甲战士     | 内蒙   |    NULL |   NULL |+--------+--------------+--------+---------+--------+

4. WHERE过滤器

这一步很简单,条件为city="内蒙" ,即只保留下city为内蒙的列,并生成新的虚拟表VT4。最终结果如下。

+--------+--------------+--------+---------+--------+| userId | userName     | city   | orderId | userId |+--------+--------------+--------+---------+--------+|      1 | 张三         | 内蒙   |   10005 |      1 ||      1 | 张三         | 内蒙   |   10004 |      1 ||      1 | 张三         | 内蒙   |   10002 |      1 ||      1 | 张三         | 内蒙   |   10001 |      1 ||      2 | 李四         | 内蒙   |   10007 |      2 ||      5 | 金甲战士     | 内蒙   |    NULL |   NULL |+--------+--------------+--------+---------+--------+

5. GROUP BY 分组

这步将上一个步骤进行分组,并生成新的虚拟表VT5,结果如下。

+--------+--------------+--------+| userId | userName     | city   |+--------+--------------+--------+|      1 | 张三         | 内蒙   ||      2 | 李四         | 内蒙   ||      5 | 金甲战士     | 内蒙   |+--------+--------------+--------+

6.HAVING筛选

分完组,我们就可以筛选了,选出count(orders.orderId)<3 的数据即可,最终结果如下。

| userId | userName     | city   | count(orders.orderId) |+--------+--------------+--------+-----------------------+|      2 | 李四         | 内蒙   |                     1 ||      5 | 金甲战士     | 内蒙   |                     0 |+--------+--------------+--------+-----------------------+

7.处理SELECT列表

虽然SELECT是查询中最先被指定的部分,但是直到这里才真正进行处理,在这一步,将SELECT中指定的列从上一步产生的虚拟表中选出。

8.应用DISTINCT

如果查询语句中存在DISTINCT子句,则会创建一张内存临时表,这张内存临时表的表结构和上一步产生的虚拟表一样,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来去除重复数据。

另外对使用了GROUP BY语句的查询,再使用DISTINCT是多余的,因为已经进行了分组,不会移除任何行。

9.排序和LIMIT

最后就是排序,返回新的虚拟表。结果如下。

+--------------+-------+| userName     | total |+--------------+-------+| 李四         |     1 || 金甲战士     |     0 |+--------------+-------+

但是在本例子中没有使用到LIMIT,如果使用到了,那么则从选出指定位置开始的指定行数

感谢你能够认真阅读完这篇文章,希望小编分享的"MySQL中逻辑查询的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

内蒙 张三 查询 数据 战士 金甲 结果 语句 李四 逻辑 西藏 生成 分析 就是 篇文章 笛卡尔 处理 乘积 条件 选出 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司排名 亿人帮互联网科技有限公司 奇酷互联网科技 为想互联网科技 卫星互联网科技股票 宁波青枫互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 阿里互联网科技公司 互联网科技商业 互联网科技产业特征 深圳艾果互联网通讯科技 世界互联网领先科技成果获奖 为客找房互联网科技公司怎么样 互联网科技圈年度人物 山东子淼互联网科技有限公司 电子商务与互联网科技的关系 产业互联网科技服务公司 广州有谷有贝互联网科技有限公司 北京互联网科技类企业分布 互联网 科技节活动 微视频大赛 互联网科技园 万易互联网科技有限公司 北京互联网络科技有限公司 银优互联网科技有限公司 云创客互联网科技公司 互联网科技教育视频 允成互联网科技有限公司融资 沐思想互联网科技有限公司 2021世界互联网领先科技成果发布 网互联网络科技
0