SQL 复杂查询
目录
复杂查询
一、目的和要求
二、实验内容
(1)查询出所有水果产品的类别及详情。
查询出编号为“00000001”的消费者用户的姓名及其所下订单。(分别采用子查询和连接方式实现)
查询出每个订单的消费者姓名及联系方式。
在(3)的基础上查出每个订单的消费者姓名和助农商户姓名。
查询出所有消费者用户的用户名和订单信息。
查询出所有类别的类别名称,对应的水果产品名称和单价。
查出所有平均库存比“核果类”类别的高的所有类别名称。
统计出“浆果类”类别的总库存。
查询出所有没有订单的消费者用户信息。
3、实验分析讨论
查询 1(使用子查询和连接):
查询 2(使用旧式连接和 IN 子查询):
不考虑数据库管理系统的自动优化(没有排序和索引)
假设订单表已经按照消费者编号和水果编号进行排序
结论:
使用 SSMS 查询计划观察
三、实验小结
总体来说,关键步骤包括:
完整代码
复杂查询
一、目的和要求
1、了解笛卡尔积,外连接与内连接,等值连接与自然连接的结果运算方式。
2、熟悉连接运算的sql语句语法。
3、学会使用子查询和连接运算查询出所需来源于多张表的数据。
二、实验内容
1、附加或还原前面实验所建立的助农水果销售系统数据库,数据库名为ZNSGXS。如自己没有备份,可以直接执行所附的实验二.sql。
2、复杂查询练习:查询语句可以直接保存为扩展名为sql的文本文件,可以把本次实验所用的程序放到一个文本文件中, sql语句需写入实验报告。
(1)查询出所有水果产品的类别及详情。
select CategoryName,Remark,FruitName from (select * from FruitCategory) as A
join
(select CategoryID,FruitName from Fruit) as B
on A.CategoryID=B.CategoryID
-
查询出编号为“00000001”的消费者用户的姓名及其所下订单。(分别采用子查询和连接方式实现)
select A.ConsumerName,C.FruitID,C.OrderDate,C.OrderID,C.Quantity from (select UserID,ConsumerName from Consumer
where UserID='user001' ) as A
join
(select * from Orders
where UserID='user001')as C
on A.UserID=C.UserID
select B.ConsumerName, OrderID, OrderDate, Quantity, FruitID
from Orders as A,Consumer as B
where A.UserID = 'user001'
AND B.UserID IN (select UserID from Consumer where UserID = 'user001');
-
查询出每个订单的消费者姓名及联系方式。
select A.ConsumerName,A.ContactNumber,B.OrderID from (select UserID,ConsumerName,ContactNumber from Consumer)as A
join
(select UserID,OrderID from Orders) as B
on A.UserID=B.UserID
-
在(3)的基础上查出每个订单的消费者姓名和助农商户姓名。
select A.ConsumerName,B.OrderID,D.MerchantName from ((select UserID,ConsumerName,ContactNumber from Consumer)as A
join
(select UserID,OrderID,FruitID from Orders) as B
on A.UserID=B.UserID)
join
(select FruitID,MerchantID from Fruit) as C
on B.FruitID=c.FruitID
join
(select MerchantID,MerchantName from Merchant) as D
on D.MerchantID=C.MerchantID
-
查询出所有消费者用户的用户名和订单信息。
select A.UserName,OrderID,OrderDate,FruitID,Quantity from (select UserID,UserName from Consumer) as A
join
(select * from Orders) as B
on A.UserID=B.UserID
-
查询出所有类别的类别名称,对应的水果产品名称和单价。
select A.FruitName,A.UnitPrice,B.CategoryName from (select FruitName,CategoryID,UnitPrice from Fruit) as A
join
(select CategoryID,CategoryName from FruitCategory) as B
on A.CategoryID=B.CategoryID
-
查出所有平均库存比“核果类”类别的高的所有类别名称。
select A.CategoryName, A.CategoryID from (select CategoryID, CategoryName from FruitCategory) as A
join
(select categoryid, stock from fruit) as B
on A.CategoryID= B.CategoryID
group by A.CategoryName, A.CategoryID
having avg(b.stock) > (
select avg(stock) from fruit
join
fruitcategory
on fruit.CategoryID = fruitcategory.CategoryID
where fruitcategory.CategoryName = '核果类'
);
-
统计出“浆果类”类别的总库存。
select sum(stock)as'浆果类总库存' from fruit
join
fruitcategory
on fruit.CategoryID = fruitcategory.CategoryID
where fruitcategory.CategoryName = '浆果类'
-
查询出所有没有订单的消费者用户信息。
select C.* from Consumer as C
left join
Orders as O
on C.UserID = O.UserID
where O.OrderID is null;
- 查询出所有有订单的消费者用户信息。
select distinct C.* from Consumer as C
inner join
Orders as O
on C.UserID = O.UserID;
3、实验分析讨论
对复杂查询练习的第2小题进行分析,如果不考虑数据库管理系统的自动优化(即假设数据没有采用任何方式排序),仅考虑运算方式,哪种查询的效率更高,为什么?再假设实际数据库订单表中已经按照消费者编号,水果编号进行排序,但仍不考虑数据库管理系统的自动优化,哪种查询的效率更高,为什么?再使用SSMS的查询计划观察两个语句的查询计划是否一致,验证自动优化后的结果。
查询分析
查询 1(使用子查询和连接):
select A.ConsumerName,C.FruitID,C.OrderDate,C.OrderID,C.Quantity from (select UserID,ConsumerName from Consumer
where UserID='user001' ) as A
join
(select * from Orders
where UserID='user001')as C
on A.UserID=C.UserID
内层的第一个子查询 (SELECT UserID, ConsumerName FROM Consumer WHERE UserID = 'user001') 执行时,从 Consumer 表中筛选出 UserID = 'user001' 的消费者信息。此操作可能会扫描整个 Consumer 表。
第二个内层子查询 (SELECT * FROM Orders WHERE UserID = 'user001') 从 Orders 表中筛选出 UserID = 'user001' 的所有订单信息,通常会对整个 Orders 表进行扫描。
外层查询执行 内连接 (JOIN),将两个子查询的结果通过 UserID 字段进行连接。
如果没有索引,查询需要对 Consumer 和 Orders 表进行全表扫描。
由于查询中使用了子查询,数据库需要首先完成子查询操作,再进行连接。
子查询的执行可能会重复计算,如果数据量很大,性能会受到影响,尤其是每个子查询都可能执行一次全表扫描。
查询 2(使用旧式连接和 IN 子查询):
select B.ConsumerName, OrderID, OrderDate, Quantity, FruitID
from Orders as A,Consumer as B
where A.UserID = 'user001'
AND B.UserID IN (select UserID from Consumer where UserID = 'user001');
IN 子查询 (SELECT UserID FROM Consumer WHERE UserID = 'user001') 从 Consumer 表中筛选出特定的 UserID,类似于查询 1 中的第一个子查询,但此时子查询会在整个查询执行之前执行一次,确定用户 user001 的 UserID。
外层查询 Orders AS A, Consumer AS B 使用 笛卡尔积(Cross Join) 来连接 Orders 和 Consumer 表,查询条件限定了 A.UserID = 'user001' 和 B.UserID = 'user001',使得笛卡尔积结果通过 WHERE 条件被过滤。
IN 子查询的执行通常需要对 Consumer 表进行扫描。假设 Consumer 表比较大,可能需要执行全表扫描。
由于 IN 子查询可能会执行多次,且笛卡尔积可能产生大量的中间结果,查询的效率较低,尤其在数据量大的情况下。
不考虑数据库管理系统的自动优化(没有排序和索引)
从执行顺序来看,查询 1(子查询和连接)需要对 Consumer 和 Orders 表分别执行子查询,连接时再进行一次匹配,导致重复计算。
查询 2(IN 子查询)也会执行全表扫描,但它的结构相对简单一些。IN 子查询会首先执行一次,结果然后传递给主查询。
在没有排序和索引的情况下,查询 2 会稍微高效一些,因为它没有重复的子查询执行,且连接操作相对简单一些。虽然 IN 子查询存在一定的性能问题,但它不会导致每个外层查询都进行子查询的重复执行。
假设订单表已经按照消费者编号和水果编号进行排序
假设 Orders 表已经按照 UserID 和 FruitID 排序,查询 1(子查询和连接)
排序优化:
如果 Orders 表已经按照 UserID 排序,连接操作可以利用排序来提高效率,减少数据扫描的成本。数据库系统可以使用 合并连接(Merge Join) 来连接已排序的表。
由于数据已经排序,合并连接可能会比哈希连接等算法更高效,减少了排序的开销。
查询 2(旧式连接和 IN 子查询)
排序优化:
如果 Orders 表已经排序,IN 子查询的优化效果较小。IN 子查询依然需要对 Consumer 表进行扫描,而且连接仍然是通过 WHERE 子句过滤的,排序不会对 IN 子查询的效率产生显著的优化效果。
结论:
在 Orders 表已排序的情况下,查询 1(子查询) 的效率会大大提高,特别是如果数据库能够利用合并连接(Merge Join)来利用排序。
使用 SSMS 查询计划观察
三、实验小结
查询所有水果产品的类别及详情
使用 JOIN 语句将 FruitCategory 和 Fruit 表连接,通过 CategoryID 提取水果类别及其详细信息。这样可以查询每个水果所属的类别和水果名称。
查询编号为“user001”的消费者用户的姓名及其所下订单
通过多表联接查询,获取特定消费者的姓名以及该消费者所下的所有订单信息,包括水果编号、订单日期和数量。
查询每个订单的消费者姓名及联系方式
使用 INNER JOIN 将 Consumer 表和 Orders 表连接,查询每个订单对应的消费者姓名和联系方式。
查询每个订单的消费者姓名和助农商户姓名
通过多次表连接,获取每个订单的消费者信息以及与其相关联的商户姓名,形成完整的订单信息链。
查询所有消费者用户的用户名和订单信息
将 Consumer 和 Orders 表进行连接,查询所有消费者的用户名和他们所下的所有订单信息。
查询所有类别的类别名称,对应的水果产品名称和单价
通过连接 Fruit 和 FruitCategory 表,获取每种水果的名称、类别和单价。
查出所有平均库存比“核果类”类别的高的所有类别名称
通过子查询计算“核果类”的平均库存,再筛选出库存高于该值的其他类别,确保数据准确并满足条件。
统计“浆果类”类别的总库存
使用 SUM() 聚合函数计算“浆果类”水果的总库存,确保查询的是该类别下所有水果的库存总和。
查询所有没有订单的消费者用户信息
通过 LEFT JOIN 查询所有没有下订单的消费者信息,确保未下订单的消费者也能被正确提取。
查询所有有订单的消费者用户信息
使用 INNER JOIN 查找所有下过订单的消费者信息,确保返回的仅为那些有订单记录的消费者。
总体来说,关键步骤包括:
连接表:通过 JOIN 连接不同的表来获取更丰富的数据。
筛选数据:使用 WHERE 或子查询来筛选满足特定条件的数据。
聚合函数:例如使用 SUM() 来计算库存的总和。
完整代码
--查询出所有水果产品的类别及详情。
select CategoryName,Remark,FruitName from (select * from FruitCategory) as Ajoin(select CategoryID,FruitName from Fruit) as Bon A.CategoryID=B.CategoryID--查询出编号为“00000001”的消费者用户的姓名及其所下订单。
select A.ConsumerName,C.FruitID,C.OrderDate,C.OrderID,C.Quantity from (select UserID,ConsumerName from Consumerwhere UserID='user001' ) as Ajoin(select * from Orders where UserID='user001')as Con A.UserID=C.UserID select B.ConsumerName, OrderID, OrderDate, Quantity, FruitID
from Orders as A,Consumer as B
where A.UserID = 'user001'AND B.UserID IN (select UserID from Consumer where UserID = 'user001');--查询出每个订单的消费者姓名及联系方式。
select A.ConsumerName,A.ContactNumber,B.OrderID from (select UserID,ConsumerName,ContactNumber from Consumer)as Ajoin (select UserID,OrderID from Orders) as Bon A.UserID=B.UserID--在(3)的基础上查出每个订单的消费者姓名和助农商户姓名。
select A.ConsumerName,B.OrderID,D.MerchantName from ((select UserID,ConsumerName,ContactNumber from Consumer)as Ajoin (select UserID,OrderID,FruitID from Orders) as Bon A.UserID=B.UserID)join (select FruitID,MerchantID from Fruit) as Con B.FruitID=c.FruitIDjoin(select MerchantID,MerchantName from Merchant) as Don D.MerchantID=C.MerchantID--查询出所有消费者用户的用户名和订单信息。
select A.UserName,OrderID,OrderDate,FruitID,Quantity from (select UserID,UserName from Consumer) as Ajoin(select * from Orders) as Bon A.UserID=B.UserID--查询出所有类别的类别名称,对应的水果产品名称和单价。
select A.FruitName,A.UnitPrice,B.CategoryName from (select FruitName,CategoryID,UnitPrice from Fruit) as Ajoin(select CategoryID,CategoryName from FruitCategory) as Bon A.CategoryID=B.CategoryID--查出所有平均库存比“核果类”类别的高的所有类别名称。select A.CategoryName, A.CategoryID from (select CategoryID, CategoryName from FruitCategory) as Ajoin (select categoryid, stock from fruit) as Bon A.CategoryID= B.CategoryIDgroup by A.CategoryName, A.CategoryIDhaving avg(b.stock) > (select avg(stock) from fruit join fruitcategory on fruit.CategoryID = fruitcategory.CategoryIDwhere fruitcategory.CategoryName = '核果类');--统计出“浆果类”类别的总库存。select sum(stock)as'浆果类总库存' from fruit join fruitcategory on fruit.CategoryID = fruitcategory.CategoryIDwhere fruitcategory.CategoryName = '浆果类'--查询出所有没有订单的消费者用户信息。
select C.* from Consumer as Cleft join Orders as O on C.UserID = O.UserIDwhere O.OrderID is null;--查询出所有有订单的消费者用户信息。
select distinct C.* from Consumer as Cinner join Orders as O on C.UserID = O.UserID;
相关文章:

SQL 复杂查询
目录 复杂查询 一、目的和要求 二、实验内容 (1)查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。(分别采用子查询和连接方式实现) 查询出每个订单的消费者姓名及联系方式。 在…...

银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法
银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法 1、支持环境2、详细操作说明步骤1:用root账户登录电脑步骤2:导航到kylin-wm-chooser目录步骤3:编辑default.conf文件步骤4:重启电脑 3、结语 Ὁ…...

抓包之使用chrome的network面板
写在前面 本文看下工作中非常非常常用的chrome的network面板功能。 官方介绍:地址。 1:前置 1.1:打开 右键-》检查,或者F12。 1.2:组成部分 2:控制器常用功能 详细如下图: 接着我们挑选其…...
避坑ffmpeg直接获取视频fps不准确
最近在做视频相关的任务,调试代码发现一个非常坑的点,就是直接用ffmpeg获取fps是有很大误差的,如下: # GPT4o generated import ffmpegprobe ffmpeg.probe(video_path, v"error", select_streams"v:0", sho…...

大数据新视界 -- 大数据大厂之 Hive 函数库:丰富函数助力数据处理(上)(11/ 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
深入解析 Django 中数据删除的最佳实践:以动态管理镜像版本为例
文章目录 引言场景与模型设计场景描述 删除操作详解1. 删除单个 Tag2. 批量删除 Tags3. 删除前确认4. 日志记录 高阶优化与问题分析1. 外键约束与误删保护2. 并发删除的冲突处理3. 使用软删除 结合 Django Admin 的实现总结与实践思考 引言 在现代应用开发中,服务和…...
【java】sdkman-java多环境切换工具
#java #env #sdk #lcshand 首先我们来复习一下,可参考我原来的文章: python多个版本的切换可用pyenv nodejs多个版本的切换可用nvm 同样,java多个版本的切换可用sdkman和jenv,我偏重于使用sdkman,因为有时候我也需要…...
11.25c++继承、多态
练习: 编写一个 武器类 class Weapon{int atk; }编写3个武器派生类:短剑,斧头,长剑 class knife{int spd; }class axe{int hp; }class sword{int def; }编写一个英雄类 class Hero{int atk;int def;int spd;int hp; public:所有的…...

STM32F103外部中断配置
一、外部中断 在上一节我们介绍了STM32f103的嵌套向量中断控制器,其中包括中断的使能、失能、中断优先级分组以及中断优先级配置等内容。 1.1 外部中断/事件控制器 在STM32f103支持的60个可屏蔽中断中,有一些比较特殊的中断: 中断编号13 EXTI…...

阿里电商大整合,驶向价值竞争新航道
阿里一出手就是王炸。11月21日,阿里公布了最新动作:将国内和海外电商业务整合,成立新的电商事业群。这是阿里首次将所有电商业务整合到一起,也对电商行业未来发展有着借鉴意义。阿里为何要这么干?未来又将给行业带来哪…...
等保测评在云计算方面的应用讲解
等保测评(信息安全等级保护测评)在云计算方面的应用主要聚焦于如何满足等级保护相关要求,并确保云计算平台及其上运行的业务系统的安全性。以下是主要内容的讲解: 1. 云计算中的等保测评概述 等保测评是在我国网络安全等级保护制…...

QML TableView 实例演示 + 可能遇到的一些问题(Qt_6_5_3)
一、可能遇到的一些问题 Q1:如何禁用拖动? 在TableView下加一句代码即可: interactive: false 补充:这个属性并不专属于TableView,而是一个通用属性。很多Controls下的控件都可以使用,其主要作用就是控…...
SpringBoot(三十九)SpringBoot集成RabbitMQ实现流量削峰添谷
前边我们有具体的学习过RabbitMQ的安装和基本使用的情况。 但是呢,没有演示具体应用到项目中的实例。 这里使用RabbitMQ来实现流量的削峰添谷。 一:添加pom依赖 <!--rabbitmq-需要的 AMQP 依赖--> <dependency><groupId>org.springfr…...
前端 Vue 3 后端 Node.js 和Express 结合cursor常见提示词结构
cursor 提示词 后端提示词 请为我开发一个基于 Node.js 和Express 框架的 Todo List 后端项目。项目需要实现以下四个 RESTful API 接口: 查询所有待办事项 接口名: GET /api/get-todo功能: 从数据库的’list’集合中查询并返回所有待办事项参数: 无返回: 包含所…...

类和对象(下):点亮编程星河的类与对象进阶之光
再探构造函数 在实现构造函数时,对成员变量进行初始化主要有两种方式: 一种是常见的在函数体内赋值进行初始化;另一种则是通过初始化列表来完成初始化。 之前我们在构造函数中经常采用在函数体内对成员变量赋值的方式来给予它们初始值。例如&…...

42.接雨水
目录 题目过程解法 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 过程 发现有特殊情况就是,最高峰的地方,如果右边小于他,然后再右边也都很小的话,…...
使用Java代码操作Kafka(五):Kafka消费 offset API,包含指定 Offset 消费以及指定时间消费
文章目录 1、指定 Offset 消费2、指定时间消费 1、指定 Offset 消费 auto.offset.reset earliest | latest | none 默认是 latest (1)earliest:自动将偏移量重置为最早的偏移量,–from-beginning (2)lates…...

Ubuntu安装不同版本的opencv,并任意切换使用
参考: opencv笔记:ubuntu安装opencv以及多版本共存 | 高深远的博客 https://zhuanlan.zhihu.com/p/604658181 安装不同版本opencv及共存、切换并验证。_pkg-config opencv --modversion-CSDN博客 Ubuntu下多版本OpenCV共存和切换_ubuntu20如同时安装o…...

突破内存限制:Mac Mini M2 服务器化实践指南
本篇文章,我们聊聊如何使用 Mac Mini M2 来实现比上篇文章性价比更高的内存服务器使用,分享背后的一些小的思考。 希望对有类似需求的你有帮助。 写在前面 在上文《ThinkPad Redis:构建亿级数据毫秒级查询的平民方案》中,我们…...

【排版教程】Word、WPS 分节符(奇数页等) 自动变成 分节符(下一页) 解决办法
毕业设计排版时,一般要求每章节的起始页为奇数页,空白页不显示页眉和页脚。具体做法如下: 1 Word 在一个章节的内容完成后,在【布局】中,点击【分隔符】,然后选择【奇数页】 这样在下一章节开始的时&…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...