【SQL基础】【牛客网】子查询、联表查询

news2024/11/15 11:29:41

子查询

基本语法

子查询,也称为嵌套查询,是在另一个 SQL 语句中嵌套的查询。子查询的结果可以被主查询(外部查询)使用,用于满足更复杂的数据检索需求。

例如:

SELECT employee_name
FROM employees
WHERE department_id = (
    SELECT department_id
    FROM departments
    WHERE department_name = 'Sales'
);

这样的查询是找department_name=“Sales"的employee的name, 涉及到多张表,因此需要用子查询建立一张新的表,来和现有的表进行操作。
子查询常用在 WHERE 子句和 FROM 子句后边:当用于 WHERE 子句时,根据不同的运算符,子查询可以返回单行单列、多行单列、单行多列数据。子查询就是要返回能够作为 WHERE 子句查询条件的值。当用于 FROM 子句时,一般返回多行多列数据,相当于返回一张临时表,这样才符合 FROM 后面是表的规则。这种做法能够实现多表联合查询。

相关题目

OrderItems 表

order_numitem_price
a110
a21
a21
a42
a55
a21
a77

Orders 表

order_numcust_id
a1cust10
a2cust1
a2cust1
a4cust2
a5cust5
a2cust1
a7cust7
SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT DISTINCT order_num
    FROM OrderItems
    where item_price >= 10)

其实就是对于子查询的简单应用。
子查询的难度并不高,只要明白,子查询可以创建出临时的表(单行单列也可以算一张表),而创建出的表是用来辅助查询的即可。

联表查询

基本语法

联表查询往往是建立在两个表存在关系上的。例如a表的外键是b表的主键,而我们需要将两个表的内容综合起来看,才能查询得到想要的内容,这就是联表查询。

例如:

# Employee表:
EmployeeID | Name      | DepartmentID
1          | John      | 2
2          | Jane      | 1
3          | Emily     | 3
# Department表
DepartmentID | DepartmentName
1            | Sales
2            | Engineering
3            | Marketing

如果我们想查询每个员工的所在部门,那只看一个表是肯定做不到的。如果不使用子查询,就还可以使用联表查询,将D表的主键和E表的外键拼接起来,凑成一个新的表(暂时的),在这个新表中我们就可以进行查询。

SELECT E.Name, D.DepartmaentName
FROM Employee
INNER JOIN Department
ON Employees.DepartmentID = Departments.DepartmentID;

不难看出,inner join的操作就是链接的操作,而on则是连接的条件。那么我们可以得到联表查询的基本语法:

SELECT table1.column1, table2.column2...
FROM table1
JOIN table2
ON table1.common_column1 = table2.common_column2;

也可以进行简化的写:

SELECT table1.column1, table2.column2...
FROM table1,table2
WHERE table1.common_column1 = table2.common_column2;

另外,如果两个表的关联字段名相同,也可以用using关键字来进行化简:

SELECT A.id, B.id
FROM A
JOIN B
ON A.id=B.id
# 简化写法
SELECT A.id, B.id
FROM A
JOIN B
USING (id)

注意

联表查询是生成一张暂时的表,在on结束后就消失。因此我们要清楚执行顺序往往是这样的:

  1. FROM/JOIN:确定要查询的主表和需要联接的其他表。
  2. WHERE:基于指定的条件对FROM子句返回的结果进行筛选。
  3. GROUP BY:将筛选后的数据按照一个或多个列进行分组。
  4. HAVING:对分组后的结果进行进一步的筛选,使用聚合函数作为条件。
  5. SELECT:选择需要返回的列。如果在SELECT子句中使用了聚合函数,这一步也会执行聚合操作。
  6. DISTINCT:如果指定了DISTINCT,则在这一步去除重复的行。
  7. ORDER BY:根据指定的列对结果进行排序。
    也就是说,SQL 先根据 ON 生成一张临时表,然后再根据 WHERE 对临时表进行筛选。

下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
在这里插入图片描述

相关题目

(1)

Customers 表

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221ann
cust2217hex

Orders 表

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

OrderItems 表

order_numquantityitem_price
a110100
a22010
a31015
a42550
a51525
a777

【问题】返回 Customers 表中的顾客名称(cust_name)和 Orders 表中的相关订单号(order_num),添加第三列 OrderTotal,其中包含每个订单的总价,并按顾客名称再按订单号对结果进行升序排序。

SELECT c.cust_name, o.order_num, quantity * item_price as OrderTotal
FROM Customers as c, Orders as o, OrderItems as i
where c.cust_id=o.cust_id AND o.order_num = i.order_num
ORDER BY c.cust_name, o.order_num;

这是一种方法,我们用联表查询将三张表建立成一张暂时的表,并且查找对应的内容。
如果我们想用聚合函数SUM,就要这么写:

SELECT c.cust_name, o.order_num, SUM(quantity * item_price) AS OrderTotal
FROM Customers c,Orders o,OrderItems oi
WHERE c.cust_id = o.cust_id AND o.order_num = oi.order_num
GROUP BY c.cust_name, o.order_num
ORDER BY c.cust_name, o.order_num

因为聚合函数是对一组数据进行汇总并返回单一结果,因此如果不加group by去进行分组的话,我们得到的就只有一行:
在这里插入图片描述
其实可以简单粗暴的得出一个结论:**如果使用聚合函数,那么我们最好将SELECT的属性都进行分组。**如果你在 SELECT 中使用了聚合函数,但没有对非聚合属性进行分组,SQL引擎将无法确定如何将这些字段与聚合结果结合,这会导致语法错误或者不正确的结果。就像本题中如果不加group by,引擎就不知道如何对聚合的结果分组。

(2)

OrderItems 表

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表

order_numcust_idorder_date
a0001cust12022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

【问题】编写 SQL 语句,使用子查询来确定哪些订单(在 OrderItems 中)购买了 prod_id 为 “BR01” 的产品,然后从 Orders 表中返回对应的顾客 ID(cust_id)和订单日期(order_date),按订购日期对结果进行升序排序

SELECT cust_id, order_date
FROM Orders
WHERE order_num in ( SELECT order_num
		FROM OrderItems
		WHERE prod_id="BR01")
ORDER BY order_date

#或者用联表查询
SELECT cust_id, order_date
FROM Orders as o, OrderItems as oi
WHERE o.order_num=oi.order_num and oi.prod_id="BR01"
ORDER BY order_date;

(3)

OrderItems 表

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表

order_numcust_idorder_date
a0001cust12022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

Customers 表

cust_idcust_email
cust1cust1@cust.com
cust2cust2@cust.com

【问题】返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(Customers 表中的 cust_email),结果无需排序。

SELECT cust_mail
FROM OrderItems as oi, Orders as o, Customers as c
WHERE oi.order_num=o.order_num AND c.cust_id=o.cust_id AND prod_id="BR01"

(4)

OrderItems 表

order_numitem_pricequantity
a110105
a211100
a21200
a421121
a5510
a2119
a775

Orders 表

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

Customers 表

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221ann
cust2217hex

【问题】编写 SQL 语句,返回订单总价不小于 1000 的客户名称和总额(OrderItems 表中的 order_num)。

SELECT cust_name, item_price*quantity as total_price
FROM Customers c,Orders o,OrderItems oi
WHERE c.cust_id = o.cust_id AND oi.order_num = o.order_num AND total_price>=1000
ORDER BY total_price

注意,这是一个错误的示范:上面的文章提到过,select操作的执行顺序是晚于from和where以及join的,因此total_price是没法被找到的,因此会执行出空结果。

SELECT cust_name, oi.total_price
FROM Customers c,Orders o, 
	(SELECT order_num, (item_price * quantity) as total_price
	 FROM OrderItems
	 WHERE item_price * quantity >1000) as oi
WHERE c.cust_id = o.cust_id AND oi.order_num = o.order_num
ORDER BY oi.total_price
# 或者这样
SELECT cust_name, SUM(item_price * quantity) AS total_price
FROM Customers
INNER JOIN Orders USING(cust_id)
INNER JOIN OrderItems USING(order_num)
GROUP BY cust_name
HAVING total_price >= 1000
ORDER BY total_price

这样可以通过子查询先构建出oi这个临时表,临时表中有total_price,再进行联表查询,就会简单。

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

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

相关文章

优化的热点分析与异常值分析:让数据分析更加便捷高效

热点分析作为一种常用的空间统计方法,能够帮助我们识别地理空间中的热点和冷点区域,即那些高值或低值集中出现的地方。而优化的热点分析进一步简化了这一过程,使用户无需手动调整参数即可获得可靠的结果。此外,异常值分析则专注于…

学习记录——day35 数据库 sqlite3

目录 一、安装sqlite3数据库以及sqlite3函数库 二、数据库的结构 三、常用数据库类型 1、sqlite3 2、mysql 四、sqlite3数据库的使用 1、打开数据库 2、sqlite3数据库中指令的使用 1)界面指令 2)操作指令 3)大小写敏感性 3、创建表…

基于STM32开发的智能家居灯光控制系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化灯光控制逻辑传感器数据采集Wi-Fi通信与远程控制应用场景 家庭智能灯光管理办公室与商业环境的智能照明常见问题及解决方案 常见问题解决方案结论 1. 引言 随着智能家居技术的普及…

尚品汇-购物车列表、临时用户购物车与登录用户购物车合并实现(三十七)

目录: (1)功能—展示购物车列表 (2)在web-all添加前端实现 (3)功能--合并购物车 (1)功能—展示购物车列表 购物车列表接口:CartService /*** 通过用户Id …

Ps:高速缓存机制

Photoshop 的高速缓存 Cache技术利用缓存和分块的方法处理图像数据,通过合理设置高速缓存级别和拼贴大小,可以有效地提升软件在处理图像时的性能。 Ps菜单:编辑/首选项 Edit/Preferences “首选项”中提供了 8 种高速缓存级别。 增加高速缓存…

一文带你读懂反向代理服务器

文章目录 一、什么是反向代理?二、反向代理的主要特点2.1 负载均衡2.2 隐藏IP2.3 响应加速2.4 过滤非法请求 三、反向代理的应用场景3.1 负载均衡3.2 SSL/TLS终止3.3 日志记录3.4 URL重写3.5 API网关3.6 CDN服务 四、区分反向代理和正向代理4.1 从工作原理上4.2 从安…

Memcached:单节点、集群案例;概念、工作原理

目录 案例前置知识点 Memcached 概念 部署场景 Memcached常用架构 流程 Memcached Memcached API 数据存储方式 数据过期方式 LRU Lazy Expiration Memcached缓存机制 Memcached路由算法 求余数hash算法 一致性hash算法 Memcached分布式 案例 单节点Memcach…

2024电工杯B题完整论文

大学生平衡膳食食谱的优化设计及评价 摘要 大学阶段是学生获取知识和身体发育的关键时期,也是形成良好饮食习惯的重要阶段。然而,当前大学生中存在饮食结构不合理和不良饮食习惯的问题,主要表现为不吃早餐或早餐吃得马虎,经常食…

如果这10道关于数据库的测试题你都会,面试必过!

一、什么是数据库测试? 数据库测试也称为后端测试。数据库测试分为四个不同的类别。 [if !supportLists] [endif]数据完整性测试 [if !supportLists] [endif]数据有效性测试 [if !supportLists] [endif]数据库相关的性能 [if !supportLists] [endif]测试功能&a…

【数据结构】二叉树顺序结构之堆的实现

1. 前言 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆 ( 一种二叉树 ) 使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两回事&…

【Python机器学习】NLP分词——利用分词器构建词汇表(二)——点积

在自然语言处理中将会有多处用到点积,点积也被称为内积,这是因为两个向量(每个向量中的元素个数)或矩阵(第一个矩阵的行数和第二个矩阵的列数)的“内部”维度必须一样,这种情况下才能相乘。这个…

【Docker】以思源笔记为例,谈谈什么是端到端加密

本文首发于 ❄️慕雪的寒舍。 链滴(思源笔记社区)里面有不少老哥似乎不太了解思源使用的端到端加密功能,以及云同步功能背后的机制。本文将以思源笔记为例,谈谈什么是端到端加密,以及思源的同步功能中用到了什么计算机…

JavaSE基础(12)——文件、递归、IO流

1、IO流 Input:输入,写数据,数据从磁盘加载到内存(程序)中。 Output:输出,读数据,数据从内存(程序)存储到磁盘中。 流:不管是读还是写&#xf…

html一文入门---标签大合集

一、文档结构标签 <!DOCTYPE html>: 声明文档类型和 HTML 版本&#xff0c;告诉浏览器使用 HTML5 解析文档。<html>: HTML 文档的根元素。<head>: 包含文档的元数据&#xff08;如标题、字符集、样式表链接&#xff09;。<title>: 定义文档的标题&…

这本书已经无敌!一本书学懂NLP自然语言(附PDF文档)

自然语言处理被誉为“人工智能皇冠上的明珠”。深度学习等技术的引入为自然语言处理技术带来了一场革命&#xff0c;尤其是近年来出现的基于预训练模型的方法&#xff0c;已成为研究自然语言处理的新范式。而今天给大家推荐的这本《自然语言处理&#xff1a;基于预训练模型的方…

详细的爱剪辑官网免费版下载步骤,还有四款剪辑工具推荐!

在当下这个数字化、自媒体蓬勃发展的时代&#xff0c;视频剪辑已成为大家日常中的一项不可或缺的技能。面对市面上丰富多样的剪辑工具&#xff0c;许多初学者往往感到困惑&#xff0c;不知道该如何选择。今天接这篇文章给大家详细解析五款常用的视频剪辑软件&#xff0c;包括还…

数字工厂管理系统与MES系统集成后有哪些作用

在当今智能制造的浪潮中&#xff0c;数字工厂管理系统与MES管理系统的深度融合与集成&#xff0c;已成为推动企业转型升级、提升生产效率与竞争力的关键路径。两者协同工作&#xff0c;不仅实现了生产过程的透明化、智能化管理&#xff0c;还促进了资源优化配置与决策支持能力的…

Python读取fasta格式数据成为字典形式。

本团队提供生物医学领域专业的AI&#xff08;机器学习、深度学习&#xff09;技术支持服务。如果您有需求&#xff0c;请扫描文末二维码关注我们。 Python读取fasta格式数据成为字典形式。 def read_fasta(file_path):"""读取FASTA格式文件&#xff0c;并返回一…

基于vue框架的毕业设计管理系统5n36i(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,教师,课题信息,题目分类,选题信息,任务书,中期检查,提交论文,论文成绩,答辩成绩,校园公告,教研主任,申报课题 开题报告内容 基于Vue框架的毕业设计管理系统开题报告 一、引言 随着高等教育的不断发展&#xff0c;毕业设计作为培…

2024年中科院SCI期刊牛顿-拉夫逊优化算法NRBO优化Transformer-LST模型的多变量时间序列预测

matlab R2024a以上 一、数据集 二、2024年中科院SCI期刊牛顿-拉夫逊优化算法NRBO 牛顿-拉夫逊优化算法(Newton-Raphson-based optimizer, NBRO)是一种新型的元启发式算法&#xff08;智能优化算法&#xff09;&#xff0c;该成果由Sowmya等人于2024年2月发表在中科院2区Top SC…