【MySQL】子查询

文章目录

  • 子查询
  • IN运算符
  • 子查询 VS 连接
  • ALL关键字
  • ANY关键字
  • 相关子查询 !
  • EXISTS运算符
  • select子句中的子查询
  • from子句中的子查询

子查询

  • 获取价格大于id为3的货物的商品
    • 用到了内查询,获取id为3的商品的单价,把结构传给外查询
  • 在where子句中编写子查询,也可以在from或select子句中编写。
use sql_store;
select *
from products
where unit_price > (select unit_pricefrom productswhere product_id = 3)

运行结果:
在这里插入图片描述

  • 练习:查询工资大于平均工资的员工
use sql_hr;
select *
from employees
where salary > (select avg(salary)from employees)

运行结果:
在这里插入图片描述

IN运算符

  • in运算符写子查询
  • 查询没有被订购过的商品,先在子查询中找出被订购过的商品id(注意要去重)。将这个查询结果作为子查询,在外层找product_id不在子查询结果里的数据,就是没有被订购过的商品。
use sql_store;
select *
from products
where product_id not in (select distinct product_idfrom order_items
)

在这里插入图片描述

  • 练习:找到没有支付过支票的客户
    • 从invoices中查询去重后的clientid,将这个结果作为内查询传给外查询,找不在这个内查询结果中的id,就是没有支付过支票的顾客
use sql_invoicing;
select *
from clients
where client_id not in (select distinct client_idfrom invoices
)

运行结果:
在这里插入图片描述

子查询 VS 连接

  • 在运行时间差不多的情况下,应该选择最易读的查询,要注意代码的可读性!
  • 上一个练习题,可以使用外连接进行查询,但这样写可读性不好。
select *
from clients
left join invoices using (client_id)
where invoice_id is null
  • 练习
    • 找到订购了货物id为3的顾客
    • 这道题用 连接查询 思路更清晰,可读性更好
-- 用子查询写
use sql_store;
select customer_id, first_name, last_name
from customers
where customer_id in (select customer_idfrom order_itemsjoin orders using (order_id)where product_id = 3
)-- 使用连接查询
select distinct customer_id, first_name, last_name
from customers
join orders using (customer_id)
join order_items using (order_id)
where product_id = 3

ALL关键字

  • 查询大于3号客户的最大发票的所有数据
use sql_invoicing;
select *
from invoices
where invoice_total > (select max(invoice_total)from invoiceswhere client_id = 3)
  • 用all关键字
    • 查询invoice_total比all后查询到的所有数据都大的数据,一个一个的跟all后查询到的结果进行比较
select *
from invoices
where invoice_total > all(select invoice_totalfrom invoiceswhere client_id = 3)

返回结果
在这里插入图片描述

  • max写法和all写法可以相互改写,两种写法的可读性都较好

ANY关键字

  • in 和 = any是等价的。
  • 查询至少有两张发票的客户id
    • 使用count(*)查到所有的信息,根据client_id分组,分组后用having进行条件筛选
select client_id, count(*)
from invoices
group by client_id
having count(*) >= 2
  • 把上述查询当子查询,把clients中至少有两张发票的客户信息查出来
    • where子句中可以用in,也可以用 = any
    • in 和 = any的效果是一样的,用哪种都行
-- in
select *
from clients
where client_id in (select client_idfrom invoicesgroup by client_idhaving count(*) >= 2
)
-- = any
select *
from clients
where client_id = any (select client_idfrom invoicesgroup by client_idhaving count(*) >= 2
)

相关子查询 !

  • 查询逻辑:先到employees表,对每个员工e执行这段子查询,计算和e同一个部门的员工的平均工资,如果这名员工e的工资高于平均工资,就会被返回在结果中。依次一条一条的去查询。
  • 这种查询成为相关子查询,子查询和外查询存在相关性,引用了外查询里出现的别名(即e)
  • 使用相关子查询时,这段子查询会在主查询每一行的层面执行,所以相关子查询经常执行的很慢。
use sql_hr;
select *
from employees e
where salary > (select avg(salary)from employeeswhere office_id = e.office_id)
  • 练习
    • 查询顾客大于自己平均值的数据
use sql_invoicing;
select *
from invoices i
where invoice_total > (select avg(invoice_total)from invoiceswhere client_id = i.client_id)

EXISTS运算符

  • 获取在发票表中有发票的客户
    • 三种写法:子查询,外连接,exists相关子查询
  • 用in,先将in后的子查询运行结果返回给where。
  • in后的子查询会生成一个列表,返回给where。如果子查询查到的过多,会导致列表特别大,这样会妨碍最佳性能;对于这种情况,用exists能提高效率
select *
from clients
where client_id in (select distinct client_idfrom invoices)
  • 用exists运算符,来查看发票表里是否存在符合这个条件的行
  • 子查询并没有给外查询返回一个结果,它会返回一个指令,说明这个子查询中是否有符合这个搜索条件的行,每一行外层查询的数据都到exists后去看是否存在;如果存在,子查询就会给exists返回true,exists运算符就会在最终结果里添加当前的记录。
select *
from clients
where exists(select client_idfrom invoiceswhere invoices.client_id = clients.client_id
);

运行结果
在这里插入图片描述

  • 练习
    • 找到从没有被订购过的商品
use sql_store;
select *
from products
where not exists(select product_idfrom order_itemswhere order_items.product_id = products.product_id
)

运行结果
在这里插入图片描述

select子句中的子查询

  • 在select子句中用子查询得到平均值
  • select语句中 在表达式中不能使用列的别名,这样就只能把select子句中的子查询再复制一遍,但是这样很长很麻烦且重复;解决方法是:再转换成一个子查询(select invoice_average)
use sql_invoicing;
select invoice_id,invoice_total,(select avg(invoice_total)from invoices) as invoice_avearge,invoice_total - (select invoice_avearge) as difference
from invoices

运行结果
在这里插入图片描述

  • 练习:得到每个客户的总发票金额,全部发票的平均值,以及他们的差值
select client_id,name,(select sum(invoice_total)from invoiceswhere client_id = c.client_id) as total_sales,(select avg(invoice_total)from invoices) as average,(select total_sales) - (select average) as difference
from clients c

运行结果
在这里插入图片描述

from子句中的子查询

  • 可以把一段查询生成的表当作另一个查询的from
select *
from(
select client_id,name,(select sum(invoice_total)from invoiceswhere client_id = c.client_id) as total_sales,(select avg(invoice_total)from invoices) as average,(select total_sales) - (select average) as difference
from clients c
) as hahah
where total_sales is not null

运行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/211786.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

车辆管控大数据可视化平台案例源码分析【可视化项目案例-10】

🎉🎊🎉 你的技术旅程将在这里启航! 🚀🚀 本专栏包括但不限于大屏可视化、图表可视化等等。订阅专栏用户在文章底部可下载对应案例源码以供大家深入的学习研究。 🎓 每一个案例都会提供完整代码和详细的讲解,不论你是初学者还是资深开发者,这里都有适合你的内容。…

【双指针】和为 s 的两个数字

和为 s 的两个数字 文章目录 和为 s 的两个数字题目描述算法思路暴力枚举双指针 代码编写Java代码C代码编写 LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode) 题目描述 购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品…

建行广东省江门市分行走进农村地区开展反假货币宣传

人民对美好生活的向往,涉及方方面面,小至“钱袋子”安全。建行广东省江门市分行落实当地监管部门部署,积极扛起维护国家金融安全的重要政治责任,深入农村地区开展反假货币宣传工作,助力构建农村反假货币工作长效机制。…

Django 入门学习总结4

视图是Django应用程序在Python语言中提供特定的方法并对应于有特定的模板的网页。网页的页面通过视图的方式进行跳转。 在投票系统中,有四个视图: 首页视图,显示最新的问题列表。细节视图,显示问题文本,通过表单可以…

算法刷题-动态规划2(继续)

算法刷题-动态规划2 珠宝的最高价值下降路径最小和使用最小花费爬楼梯整数拆分 珠宝的最高价值 题目 大佬思路 多开一行使得代码更加的简洁 移动到右侧和下侧 dp[ i ][ j ]有两种情况: 第一种是从上面来的礼物最大价值:dp[ i ][ j ] dp[ i - 1 ][ j ]…

【封装UI组件库系列】封装Icon图标组件

封装UI组件库系列第三篇封装Icon图标组件 🌟前言 🌟封装Icon 1.创建Icon组件 2.引用svg图标库 第一步 第二步 第三步 3.二次封装 4.封装自定义属性 🌟总结 🌟前言 在前端开发中,大家可能已经用过各种各样的UI组…

cookie的跨站策略 跨站和跨域

借鉴:Cookie Samesite简析 - 知乎 (zhihu.com) 1、跨站指 协议、域名、端口号都必须一致 2、跨站 顶级域名二级域名 相同就行。cookie遵循的是跨站策略

LangChain的函数,工具和代理(一):OpenAI的函数调用

一、什么是函数调用功能 几个月前OpenAI官方发布了其API的函数调用功能(Function calling), 在 API 调用中,您可以描述函数,并让模型智能地选择输出包含调用一个或多个函数的参数的 JSON 对象。API函数“ChatCompletion” 虽然不会实际调用该函数&#…

批量创建表空间数据文件(DM8:达梦数据库)

DM8:达梦数据库 - - 批量创建表空间数据文件 环境介绍1 批量创建表空间SQL2 达梦数据库学习使用列表 环境介绍 在某些场景(分区表子表)需要批量创建表空间,给不同的表使用,以下代码是批量创建表空间的SQL语句; 1 批量创建表空间SQL --创建 24个数据表空间,每个表空间有3个数…

经典的回溯算法题leetcode组合问题整理及思路代码详解

目录 组合问题 leetcode77题.组合 leetcode216题.组合总和III leetcode40题.组合总和II leetcode39题.组合总和 倘若各位不太清楚回溯算法可以去看我上一篇文章。 回溯算法详解-CSDN博客 组合问题 一般组合和排列类的问题我们都会转化成一个树形问题,更便于…

使用Typecho搭建个人博客网站,并内网穿透实现公网访问

使用Typecho搭建个人博客网站,并内网穿透实现公网访问 文章目录 使用Typecho搭建个人博客网站,并内网穿透实现公网访问前言1. 安装环境2. 下载Typecho3. 创建站点4. 访问Typecho5. 安装cpolar6. 远程访问Typecho7. 固定远程访问地址8. 配置typecho 前言 …

通过CLSID修改Windows右键菜单顺序

效果 排序顺序: 上下文菜单分为3个区: 2 - 默认菜单部分 (在顶部). 1 - 发送到、复制到、移动到 菜单部分(在中间). 0 - 重命名菜单部分 (在底部). 调整菜单步骤: 打开regeditHKEY_CLASSES_ROOT > CLSID 键.在 CLSID, 寻找你想修改位置…