1.子查询

前面的系列介绍的都是简单的查询场景,其中都只涉及到单张表的数据检索。但是在日常是实际应用中,数据模型之间的关系都非常的复杂,数据的需求一般都是来源于多个数据模型之间的组合而成,即对应多张表的数据关联。

对应以上场景,在SQL中一般有三种实现的方式:

  • 使用多个单条SQL,按逻辑步骤检索,将其中的一条检索结果作为下一条检索的条件;
  • 使用子查询,即将多个单挑SQL利用相应的逻辑关键字合并,子查询是DBMS所支持;
  • 使用表联结的方式,即join;

本章就简单的回顾下SQL中的子查询,从上面的总结中可以看出,子查询其实利用模型之间的关系将单条SQL合并成一条复杂的SQL。那么如果要写出这样的复杂子查询的SQL,首先需要梳理清楚需求中的数据模型之间的关系,根据需求的结果区分出查询主体,查询的关联关系体,然后再分成单步骤的SQL,最后将其合并即可;

下面看个例子:

有三个实体,对应三张表:

  • 顾客表
  • 商品表
  • 订单表

订单中含有商品id,顾客id。现在需求:查询购买商品x1的所有顾客。

  1. 分析:最终的结果是要查询出顾客,所以查询柱体是顾客,即外查询是顾客。但是查询顾客的条件是,购买了x1商品的顾客,所以需要查出购买了x1商品的顾客id,然后根据顾客id查询顾客,所以子查询是根据商品id x1查询。

  2. 步骤:

  • 在表orders中查询x1商品的顾客id: select cus_id from orders where mer_id = 'x1';

  • 根据上述的查询结果作为条件,查询顾客:select * from customers where cus_id = 'xxxx';

最后将根据需求结果和实体的关联关系合并SQL:

select * from customers where customers.cus_id in (select cus_id from orders where mer_id = 'x1');

其实SQL中子查询有两种应用方式:

  • 第一种也就上面的最常使用到的场景,将子查询的结果作为外查询的条件,即子查询属于外查询where子句的一部分
  • 第二种常用是将子查询统计结果作为外查询的列

比如需求:统计每个顾客购订单数量。

  1. 分析:顾客仍然是主体,所以外查询是查顾客表。但是执行的逻辑刚好和上述例子相反,上述是以商品id为条件查询顾客。这里是查询顾客以及其订单数,但是订单数的统计是从顾客这一维度出发,所以需要根据顾客查询订单数。

  2. 步骤:

  • 先查询出所有顾客: select * from customers;
  • 再根据顾客去统计每个顾客的订单数: select count(*) from orders where orders.cus_id = 'xxxxx';

最后组合SQL:

select cus_id, cus_name, (select count(*) from orders where orders.cus_id = customers.cus_id) from customers;

以上例子是子查询的第二种用法。

2.总结

上述总结的子查询的两种方式:

  • 要么是根据子查询的逻辑结果作为外查询的查询条件(子查询在where子句中)
  • 要么是根据外查询的结果作为子查询的条件(子查询在select子句中)

SQL中没有限制子查询的数量,但是一般实际应用中子查询的不宜使用过多:

  • 使用子查询必然会导致SQL更为复杂,SQL表述的语义较为难以理解,可阅读性变差
  • 子查询使用过多,会严重消耗性能
  • 子查询不利于SQL的调试,问题的排查

SQL系列(九)—— 子查询(subQuery)的更多相关文章

  1. 【SqlServer系列】子查询

    1   概述 1.1  已发布[SqlServer系列]文章 [SqlServer系列]SQLSERVER安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 [Sq ...

  2. Sql Server系列:子查询

    1 子查询概念 子查询是嵌套在另一个查询中的普通T-SQL查询.在有一个SELECT语句通过使用小括号创建子查询,作为另一个查询的部分数据或条件的基础. 子查询通常用于满足以下某个需求: ◊ 将一个查 ...

  3. SQL语句:子查询

    一,子查询定义: 子查询就是嵌套在主查询中的查询. 子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 但并不是每个位置嵌套子 ...

  4. MySQL子查询subquery

    子查询(Subquery)是指出现在其他SQL语句内的SELECT子句. 例如: select * from t1 where col1=(select col2 from t2); 其中select ...

  5. SQL Server 数据库子查询基本语法

    一.SQL子查询语句 1.单行子查询        select ename,deptno,sal        from emp        where deptno=(select deptno ...

  6. sql之独立子查询和相关子查询总结

    1.独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的: 下面就看一个例子: 有一张订单表 Sales.Order 和一张 客户表 Sales.Customer 下面的sql ...

  7. SQL Server 之 子查询与嵌套查询

    当由where子句指定的搜索条件指向另一张表时,就需要使用子查询或嵌套查询. 1 子查询 子查询是一个嵌套在select.insert.update或delete语句或其他子查询中的查询.任何允许使用 ...

  8. 工作中遇到的比较奇怪的一些sql(一些子查询)

    在列中进行子查询 1.在一个表中有多个员工ID,比如一个下单员工,一个修改订单的员工,可以使用在列中进行子查询,具体如下: ( SELECT staff_name FROM sp_staff_basi ...

  9. 优化系列 | DELETE子查询改写优化

    0.导读 有个采用子查询的DELETE执行得非常慢,改写成SELECT后执行却很快,最后把这个子查询DELETE改写成JOIN优化过程 1.问题描述 朋友遇到一个怪事,一个用子查询的DELETE,执行 ...

  10. SQL优化-标量子查询(数据仓库设计的隐患-标量子查询)

    项目数据库集群出现了大规模节点宕机问题.经查询,问题在于几张表被锁.主要问题在于近期得几个项目在数据库SQL编写时大量使用了标量子查询. 为确定为题确实是由于数据表访问量超过单节点限制,做了一些测试. ...

随机推荐

  1. iOS批量添加SDK自动打包GUI工具

    背景 1.之前在给游戏开发商做SDK接入技术支持的时候,很多cp对iOS开发技术并不是很了解,对接SDK和打包都很迷糊,虽然我们根据他们的开发环境输出了不同的插件解决方案,这一步已经把接入SDK的复杂 ...

  2. 结对项目(JAVA)

    项目成员: 邓镇港 3117004608 陈嘉欣 3117004604 一.Github项目地址: https://github.com/kestrelcjx/operation_expression ...

  3. React源码 memo Fragment StrictMode cloneElement createFactory

    1.memo react 16.6 推出的 api ,他的用意是给 function component 也有 PureComponent 这样一个类似的功能,因为我们知道 PureComponent ...

  4. 【转】Pandas学习笔记(六)合并 merge

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  5. django 权限设置-菜单显示

    问题:在用户登录后,如何只显示出用户权限的菜单呢?需要设置显示菜单权限 1.为了显示菜单,需要在models权限上添加is_menu(手动判断是否是查看)的icon(图标字符串) 在rbac中录入另一 ...

  6. django模板中的extends和include使用方法

    一.extends使用方法 首先extends也就是继承,子类继承父类的一些特性.在django模板中通过继承可以减少重复代码. 首先我们建立一个app,名字叫做hello.别忘了在settings. ...

  7. 小学四则运算口算练习app---No.3

    今天主要是实现按照指定的题目出题数目出题.在昨天设置页面的基础上,今天首先要学习的是接收不同页面间的参数问题.详解如下: 然后就开始我的传参和接收参数的问题! 在当前的Activity上进行跳转, 代 ...

  8. sessionId控制单点登陆

    1.配置security-context.xml文件 <?xml version="1.0" encoding="UTF-8"?><beans ...

  9. W5500 学习开发: W5500学习说明

    前言 官方已经给了大部分的例子,我只是做一下移植说明 这一节看一下如何移植官网程序的DHCP 首先先明确:单片机和W5500通信是通过SPI,所有的数据都是通过SPI接收和发送, 所以,拿到官方源码只 ...

  10. SpringData JPA一对多多对一多对多关联

    一.一对多.多对一 1.Country实体类 2.City实体类 3.CountryDao层 4.CityDao层 5.Controller package com.zn.controller; im ...