SQL - 子查询

  • 子查询可以写的位置:select、from、where

  • 子查询可以返回一个值:一个列的一些值,一个结果集(表)

  • 子查询的作用:可以作为条件判断的范围,作为判断条件,可以返回特定结果值,

  • 与子查询相关:

    • in 运算符;

      • in (子查询),其中子查询返回的结果是一个结果集
      sql 复制代码
      select *
      from clients
      where client_id in (
      select client_id
      from invoices
      group by client_id
      having count(*)>2)
    • 子查询 vs 连接;

      • 子查询和连接,都能用来查询信息,比较的是可读性和查询效率
      sql 复制代码
      select *
      from clients
      where client_id not in (
      select  distinct client_id 
      from invoices)
      -- 同一个问题,连接和子查询的比较
      select *
      from clients 
      left join invoices using (client_id)
      where invoice_id is null
    • all 关键字

      • 表示一个值要比all修饰的子查询返回的一列值都大,或都小等;同理可得,any关键字和some关键字都是类似的含义。
      sql 复制代码
      select *
      from invoices
      where invoice_total > all(
      select invoice_total
      from invoices
      where client_id=3)
      -- 等价于
      -- select *
      -- from invoices
      -- where invoice_total > (
      -- select max(invoice_total)
      -- from invoices
      -- where client_id=3)
    • 相关子查询

      • 子查询和外查询存在相关性,子查询的返回结果集和外查询存在联系,但是相关子查询经常执行得很慢
      sql 复制代码
      select *
      from employees e
      where salary >(
      select avg(salary)
      from employees 
      where office_id=e.office_id)
      -- 也可以写这样,但是体现不了相关子查询的特点
      -- select *
      -- from employees
      -- join (select office_id,avg(salary) as aaa
      -- from employees
      -- group by office_id) o
      -- on o.office_id=employees.office_id
      -- where salary>aaa
    • exists 运算符(存在)

      • where exists (子查询)
      • 能够提高效率,在子查询的过程中,找到一行符合条件的记录就返回true
      sql 复制代码
      -- exists
      select *
      from clients c
      where exists (
      select client_id
      from clients
      where client_id=c.client_id)
    • select 子句中的子查询
    sql 复制代码
    select 
    	invoice_id,
        invoice_total,
        (select avg(invoice_total) from invoices) as invoice_avg,
        invoice_total- (select invoice_avg) as defference
    from invoices;
     
    select client_id,name,sum(invoice_total),
    (select avg(invoice_total) from invoices) as average,
    sum(invoice_total)-(select average) as difference
    from clients
    left join invoices using (client_id)
    group by client_id,name
    • from 子句中的子查询

      • 子查询的结果可以作为一张真实的表使用
      sql 复制代码
      select *
      from employees
      join (select office_id,avg(salary) as aaa
      from employees
      group by office_id) o
      on o.office_id=employees.office_id
      where salary>aaa
相关推荐
oradh2 小时前
Oracle TX 锁 Mode 4(Share)问题排查总结
数据库·oracle·tx 锁 mode 4·oracle tx 锁
2601_962065253 小时前
[MySQL] SQL优化之性能分析
java·sql·mysql
yi.Ist3 小时前
数据定义语言-DDL操作
数据库·学习·mysql·oracle·大海豚
阿kun要赚马内3 小时前
MySQL 索引基础
后端·mysql
2601_963282775 小时前
工程项目、政企采购为什么优先选择对讲机批量采购?
数据库
Doraemomo5 小时前
SQLite数据库
数据库·sqlite
2601_962177135 小时前
【MySQL篇】聚合查询,联合查询
android·java·mysql
云贝教育-郑老师5 小时前
MySQL 的“黑匣子“:Performance Schema 把数据库内部变成一张可查的表
数据库·mysql
这个DBA有点耶7 小时前
同城双活落地的三座山:网络延迟、脑裂预防、反向同步
数据库·架构·dba