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

  1. 查询出编号为“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');

  1. 查询出每个订单的消费者姓名及联系方式。

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

  1. 在(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

  1. 查询出所有消费者用户的用户名和订单信息。

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

  1. 查询出所有类别的类别名称,对应的水果产品名称和单价。

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

  1. 查出所有平均库存比“核果类”类别的高的所有类别名称。

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 = '核果类'

);

  1. 统计出“浆果类”类别的总库存。

select sum(stock)as'浆果类总库存' from fruit

join 

fruitcategory

on fruit.CategoryID = fruitcategory.CategoryID

where fruitcategory.CategoryName = '浆果类'

  1. 查询出所有没有订单的消费者用户信息。

select C.* from Consumer as C

left join 

Orders as O

on C.UserID = O.UserID

where O.OrderID is null;

  1. 查询出所有有订单的消费者用户信息。

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;

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

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

相关文章

Angular面试题汇总系列一

1. 如何理解Angular Signal Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates. 什么是信号 信号是一个值的包装器,可以在该值发生变化时…

ES 和Kibana-v2 带用户登录验证

1. 前言 ElasticSearch、可视化操作工具Kibana。如果你是Linux centos系统的话,下面的指令可以一路CV完成服务的部署。 2. 服务搭建 2.1. 部署ElasticSearch 拉取docker镜像 docker pull elasticsearch:7.17.21 创建挂载卷目录 mkdir /**/es-data -p mkdir /**/…

esp32触发相机

esp32触发相机&#xff0c;测试成功上升沿触发 串口发送命令 up 20000 1 20000 触发 #include <Arduino.h>const int outputPin 12; // 输出引脚 String inputCommand ""; // 串口输入缓冲区// 解析命令参数&#xff0c;例如 "up 10 5" 解析为…

【踩坑】git中文乱码问题

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 背景说明 使用git diff显示中文乱码&#xff0c;如&#xff1a; 修复方法 执行一次&#xff1a; export LESSCHARSETutf-8 如果需要下次登录免输入…

Spring Boot中配置Flink的资源管理

在 Spring Boot 中配置 Flink 的资源管理&#xff0c;需要遵循以下步骤&#xff1a; 添加 Flink 依赖项 在你的 pom.xml 文件中&#xff0c;添加 Flink 和 Flink-connector-kafka 的依赖项。这里以 Flink 1.14 版本为例&#xff1a; <!-- Flink dependencies --><de…

c++学习:json库例子

目录 初始化 解析string字符串并输出 赋值 给json赋值string&#xff0c;char *&#xff0c;QString&#xff0c;bool&#xff0c;int 赋值 将json转为string&#xff0c;char *&#xff0c;QString 删除 嵌套对象和数组的组合与解析 JSON 数组 遍历&#xff0c;添加…

【环境搭建】更新Docker Compose到v2.x版本以支持--profile选项

Docker版本陈旧也是搭建的环境起不来的一个重要原因&#xff0c;比如 --profile 选项是 Docker 20.10.0 版本及以上版本才开始支持的&#xff0c;在 Docker Compose v2.1&#xff08;及以上版本&#xff09;中引入用于对服务进行分组和按需启动。 更新 Docker Compose 到 v2.x…

网络——浏览器发送一个请求到收到响应经历了哪些步骤

当浏览器发送一个请求到服务器并收到响应时&#xff0c;通常会经历以下几个步骤。这个过程可以分为几个主要阶段&#xff1a;DNS解析、建立TCP连接、发送HTTP请求、服务器处理请求和返回响应、浏览器接收响应等。下面是更详细的步骤说明&#xff1a; 输入URL&#xff1a;用户在…

Python基础速通

Python基础速通 Python是一门强大的编程语言&#xff0c;广泛应用于数据分析、自动化、网络安全等多个领域。本文将系统地介绍Python的基础知识&#xff0c;包括环境配置、基础语法、数据结构、函数、面向对象编程以及常见的文件操作和异常处理技巧。 Python 环境安装 在开始…

.Net与C#

.NET 与 C# 的关系 .NET 是一个由微软开发的软件框架&#xff0c;它提供了一套用于开发、运行和部署应用程序的工具和库。C# 是一种面向对象的编程语言&#xff0c;它是专门为.NET平台设计的。以下是.NET与C#之间关系的详细说明&#xff1a; 目标平台&#xff1a;C# 是.NET平…

go语言逆向-基础basic

文章目录 go 编译命令 ldflags -w -s的作用和问题使用 file 命令查看文件类型 go 语言逆向参考go ID版本GOROOT和GOPATHGOROOTGOPATHGOROOT和GOPATH的关系示例 go build和 go modpclntab &#xff08;Program Counter Line Table 程序计数器行数映射表&#xff09;Moduledata程…

D2761 适合在个人电脑、便携式音响等系统中作音频限幅用。

概述&#xff1a; D2761是为保护扬声器所设计的音频限幅器&#xff0c;其限幅值可通过外接电阻来调节&#xff0c;适合在个人电脑、便携式音响等系统中作音频限幅用。D2761采用SSOP10、MSOP10、TSSOP14的封装形式封装。 主要特点&#xff1a;  工作电压范围宽&#xff1a;2.7…

【Linux系统】—— 基本指令(四)

【Linux系统】—— 基本指令&#xff08;三&#xff09; 1「find」指令2 「grep」指令2.1 初识「grep」指令2.2 「grep」指令 选项 3 打包压缩基本知识4 「zip / unzip」指令5「tar」命令6 文件互传6.1 Linux 与 Windows 互传6.1.1 Linux向Windows传输6.1.2 Windows向Linux传输…

【bug记录10】同一iOS webview页面中相同的两个svg图标出现部分显示或全部不显示的情况

一、问题背景 在vue项目中&#xff0c;同一页面中直接复制粘贴了两个相同的svg代码嵌入到html中&#xff0c; 在chrome浏览器中显示良好&#xff1b; 但是在Safari浏览器 或者 iOS WKwebview中&#xff0c;出现只显示一个svg或者两个都不显示的情况&#xff0c;但是绑定在sv…

WordCloud去掉停用词(fit_words+generate)的2种用法

-------------词云图集合------------- WordCloud去掉停用词&#xff08;fit_wordsgenerate&#xff09;的2种用法 通过词频来绘制词云图&#xff08;jiebaWordCloud&#xff09; Python教程95&#xff1a;去掉停用词词频统计jieba.tokenize示例用法 将进酒—李白process_t…

洛谷刷题日记12||图的遍历

反向建边 dfs 按题目来每次考虑每个点可以到达点编号最大的点&#xff0c;不如考虑较大的点可以反向到达哪些点 循环从N到1&#xff0c;则每个点i能访问到的结点的A值都是i 每个点访问一次&#xff0c;这个A值就是最优的&#xff0c;因为之后如果再访问到这个结点那么答案肯…

vscode查找函数调用

在 VS Code 中&#xff0c;要查找 C 语言函数的调用列表&#xff0c;有以下几种方法可以使用&#xff0c;具体取决于项目的规模和你的需求&#xff1a; 方法 1: 使用全局查找功能 步骤&#xff1a; 打开全局查找&#xff1a; 按 CtrlShiftF (Windows/Linux) 或 CmdShiftF (Ma…

替代Postman ,17.3K star!

现在&#xff0c;许多人都朝着全栈工程师的方向发展&#xff0c;API 接口的编写和调试已成为许多开发人员必备的技能之一。 工欲善其事&#xff0c;必先利其器。拥有一款优秀的 API 工具对于任何工程师来说都是极为重要的&#xff0c;它能够帮助我们高效地完成各种开发任务。 …

java:拆箱和装箱,缓存池概念简单介绍

1.基本数据类型及其包装类&#xff1a; 举例子&#xff1a; Integer i 10; //装箱int n i; //拆箱 概念&#xff1a; 装箱就是自动将基本数据类型转换为包装器类型&#xff1b; 拆箱就是自动将包装器类型转换为基本数据类型&#xff1b; public class Main {public s…

Node.js的url模块与querystring模块

新书速览|Vue.jsNode.js全栈开发实战-CSDN博客 《Vue.jsNode.js全栈开发实战&#xff08;第2版&#xff09;&#xff08;Web前端技术丛书&#xff09;》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) 4.3.1 http模块——创建HTTP服务器、客户端 要使用http模块&#xff0…