11. Mysql 子查询

Mysql 函数参考和扩展:Mysql 常用函数和基础查询Mysql 官网

Mysql 语法执行顺序如下,一定要清楚!!!运算符相关,可前往 Mysql 基础语法和执行顺序扩展。

sql 复制代码
(8) select (9) distinct (11)<columns_name list>
(1) from <left_table>
(3) <join_type> join <right_table>
(2) on <join_condition>
(4) where <where_condition>
(5) group by <group_by columns_name list>
(6) with <rollup>
(7) having <having_condition>
(10) order by <order_by columns_name list>
(12) limit <[offset,] rows>
;

数据准备

sql 复制代码
drop table if exists orderitems;
create table if not exists orderitems
(
    order_num  varchar(255) not null comment '商品订单号',
    item_price int(16)      not null comment '售出价格',
    quantity   int(16)      not null comment '商品数量'
);
insert orderitems
values ('a0001', 10, 105),
       ('a0002', 1, 1100),
       ('a0002', 1, 200),
       ('a0013', 2, 1121),
       ('a0003', 5, 10),
       ('a0003', 1, 19),
       ('a0003', 7, 5);

drop table if exists orders;
create table if not exists orders
(
    order_num varchar(255) not null comment '商品订单号',
    cust_id   varchar(255) not null comment '顾客id'
);
insert `orders`
values ('a0001', 'cust10'),
       ('a0003', 'cust1'),
       ('a0013', 'cust2');

子查询示例

子查询指一个查询语句嵌套在另一个查询语句内部的查询。又叫内部查询,相对于内部查询,包含内部查询的就称为外部查询。子查询外部必须是以下语句之一:select、insert、update、delete、set或者do。

标量子查询:是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。

可以使用 =、>、<、>=、<=、<>、! 这些操作符对子查询的标量结果进行比较。

sql 复制代码
# 单行单列,单一值
select order_num, item_price, quantity
from orderitems
where quantity = (select max(quantity) from orderitems);
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0013     |          2 |     1121 |
+-----------+------------+----------+

行子查询:指子查询返回的结果集是单行多列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。

sql 复制代码
# 单行多列
select order_num, item_price, quantity
from orderitems
where (order_num,item_price) = (select order_num,item_price
                                from orderitems
                                where quantity = 1121);
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0013     |          2 |     1121 |
+-----------+------------+----------+

列子查询:指子查询返回的结果集是多行单列,该结果通常来自对表的某个字段查询返回。

可以使用 in、not in、any、some 和 all操作符:

  • in:判断是否在这个集合中,如果在True,否则返回False。
  • not in:判断是否不在这个集合中,如果不在True,否则返回False。
  • any:需要和单行比较操作符一起使用,和子查询返回的某一个值比较,如果其中有符合,则返回True。(比最小大就行)
  • some:实际上是any的别名,作用相同,一般常使用any。
  • all:需要和单行比较操作符一起使用,和子查询返回的所有值比较,如果所有都符合,则返回True。(比最大还大)
sql 复制代码
# 多行单列
select *
from orderitems
where quantity > any(select quantity
                     from orderitems
                     where order_num = 'a0002');
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0002     |          1 |     1100 |
| a0013     |          2 |     1121 |
+-----------+------------+----------+
select *
from orderitems
where quantity > all(select quantity
                     from orderitems
                     where order_num = 'a0002');
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0013     |          2 |     1121 |
+-----------+------------+----------+

表子查询:指子查询返回的结果集是多行多列的一个表数据。

sql 复制代码
# 多行多列
select order_num, item_price, quantity
from orderitems
where (order_num,item_price,quantity)
          in (select order_num, item_price, quantity
              from orderitems
              where order_num = 'a0002');
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0002     |          1 |     1100 |
| a0002     |          1 |      200 |
+-----------+------------+----------+

关联子查询:如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为关联子查询 。

按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。

sql 复制代码
select *
from orderitems as a
where quantity > (select avg(quantity)
                  from orderitems as b
                  where a.order_num = b.order_num);
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0002     |          1 |     1100 |
| a0003     |          1 |       19 |
+-----------+------------+----------+

existsnot exists子查询:

  • exists:表示如果存在某种条件,则返回True,否则返回False。
  • not exists:表示如果不存在某种条件,则返回True,否则返回False。
sql 复制代码
select *
from orderitems as a
where exists(select *
             from orders as b
             where a.order_num = b.order_num);
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0001     |         10 |      105 |
| a0013     |          2 |     1121 |
| a0003     |          5 |       10 |
| a0003     |          1 |       19 |
| a0003     |          7 |        5 |
+-----------+------------+----------+
select *
from orderitems as a
where not exists(select *
             from orders as b
             where a.order_num = b.order_num);
+-----------+------------+----------+
| order_num | item_price | quantity |
+-----------+------------+----------+
| a0002     |          1 |     1100 |
| a0002     |          1 |      200 |
+-----------+------------+----------+

子查询的执行效率不高,尽量少使用子查询,可以使用多表连接查询代替子查询,多表连接查询不需要建立临时表,其速度比子查询要快。

相关推荐
Bruce_Liuxiaowei28 分钟前
MySQL完整重置密码流程(针对 macOS)
mysql
麦麦大数据1 小时前
F003疫情传染病数据可视化vue+flask+mysql
mysql·flask·vue·大屏·传染病
whysqwhw1 小时前
安卓图片性能优化技巧
android
薛晓刚1 小时前
当MySQL的int不够用了
数据库
风往哪边走1 小时前
自定义底部筛选弹框
android
SelectDB技术团队1 小时前
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
数据库·数据仓库·数据分析·apache doris·菜鸟技术
星空下的曙光2 小时前
mysql 命令语法操作篇 数据库约束有哪些 怎么使用
数据库·mysql
小楓12012 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
Yyyy4822 小时前
MyCAT基础概念
android
染落林间色2 小时前
达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
数据库·sql