08 SQL进阶 -- 集合运算 -- 表的连结(JOIN)

news2024/11/26 2:46:27

在这里插入图片描述

1. 连结(JOIN)

前一节我们学习了 UNION和INTERSECT 等集合运算, 这些集合运算的特征就是以行方向为单位进行操作. 通俗地说, 就是进行这些集合运算时, 会导致记录行数的增减。使用 UNION 会增加记录行数,而使用 INTERSECT 或者 EXCEPT 会减少记录行数。

但这些运算不能改变列的变化, 虽然使用函数或者 CASE表达式等列运算, 可以增加列的数量, 但仍然只能从一张表中提供的基础信息列中获得一些"引申列", 本质上并不能提供更多的信息。如果想要从多个表获取信息, 例如, 如果我们想要找出某个商店里的衣服类商品的名称,数量及价格等信息, 则必须分别从shopproduct 表和product 表获取信息。

在这里插入图片描述

注:

截至目前,本书中出现的示例(除了关联子查询)基本上都是从一张表中选取数据,但实际上,期望得到的数据往往会分散在不同的表之中, 这时候就需要使用连结了。
之前在学习关联子查询时我们发现, 使用关联子查询也可以从其他表获取信息, 但连结更适合从多张表获取信息。

连结(JOIN)就是使用某种关联条件(一般是使用相等判断谓词"="), 将其他表中的列添加过来, 进行“添加列”的集合运算. 可以说,连结是 SQL 查询的核心操作, 掌握了连结, 能够从两张甚至多张表中获取列, 能够将过去使用关联子查询等过于复杂的查询简化为更加易读的形式, 以及进行一些更加复杂的查询。

SQL 中的连结有多种分类方法, 我们这里使用最基础的内连结和外连结的分类方法来分别进行讲解。

1.1 内连结(INNER JOIN)

内连结的语法格式是:

– 内连结

FROM <tb_1> INNER JOIN <tb_2> ON <condition(s)>

其中 INNER 关键词表示使用了内连结, 至于内连结的涵义, 目前暂时可以不必细究。

例如, 还是刚才那个问题:

找出某个商店里的衣服类商品的名称,数量及价格等信息。

我们进一步把这个问题明确化:

找出北京商店里的衣服类商品的商品名称,商品价格,商品种类,商品数量信息。

1.1.1 使用内连接从两个表获取信息

我们先来分别观察所涉及的表,product 表保存了商品编号,商品名称,商品种类等信息,这个表可以提供关于衣服种类的衣服的详细信息, 但是不能提供商店信息。

在这里插入图片描述

我们接下来观察shopproduct 表, 这个表里有商店编号名称,商店的商品编号及数量. 但要想获取商品的种类及名称售价等信息,则必须借助于product 表。

在这里插入图片描述

我们来对比一下上述两张表, 可以发现, 商品编号列是一个公共列, 因此很自然的事情就是用这个商品编号列来作为连接的“桥梁”,将product和shopproduct这两张表连接起来。

首先, 找出每个商店的商店编号, 商店名称, 商品编号, 商品名称, 商品类别, 商品售价,商品数量信息。

按照内连结的语法, 在 FROM 子句中使用 INNER JOIN 将两张表连接起来, 并为 ON 子句指定连结条件为 shopproduct.product_id=product.product_id, 就得到了如下的查询语句:

SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM shopproduct AS SP
INNER JOIN product AS P
ON SP.product_id = P.product_id;

在这里插入图片描述

在上述查询中, 我们分别为两张表指定了简单的别名, 这种操作在使用连结时是非常常见的, 通过别名会让我们在编写查询时少打很多字, 并且更重要的是, 会让查询语句看起来更加简洁。

观察查询结果, 我们看到,这个结果里的列已经包含了所有我们需要的信息.

关于内连结,需要注意以下三点:

要点一: 进行连结时需要在 FROM 子句中使用多张表。

之前的 FROM 子句中只有一张表, 而这次我们同时使用了shopproduct 和product 两张表,使用关键字 INNER JOIN 就可以将两张表连结在一起了:

FROM shopproduct AS SP INNER JOIN product AS P

要点二:必须使用 ON 子句来指定连结条件。

在进行内连结时 ON 子句是必不可少的(大家可以试试去掉上述查询的 ON 子句后会有什么结果)。

ON 子句是专门用来指定连结条件的, 我们在上述查询的 ON 之后指定两张表连结所使用的列以及比较条件, 基本上, 它能起到与 WHERE 相同的筛选作用。

要点三: SELECT 子句中的列最好按照表 名.列名 的格式来使用。

当两张表的列除了用于关联的列之外, 没有名称相同的列的时候, 也可以不写表名, 但表名使得我们能够在今后的任何时间阅读查询代码的时候, 都能马上看出每一列来自于哪张表, 能够节省我们很多时间。

但是, 如果两张表有其他名称相同的列, 则必须使用上述格式来选择列名, 否则查询语句会报错。

我们回到上述查询所回答的问题. 通过观察上述查询的结果, 我们发现, 这个结果离我们的目标: 找出东京商店的衣服类商品的基础信息已经很接近了。接下来,我们只需要把这个查询结果作为一张表, 给它增加一个 WHERE 子句来指定筛选条件。

1.1.2 结合 WHERE 子句使用内连结

如果需要在使用内连结的时候同时使用 WHERE 子句对检索结果进行筛选, 则需要把 WHERE 子句写在 ON 子句的后边。

例如, 对于上述查询问题, 我们可以在前一步查询的基础上, 增加 WHERE 条件。

增加 WHERE 子句的方式有好几种,我们先从最简单的说起。

第一种增加 WEHRE 子句的方式, 就是把上述查询作为子查询, 用括号封装起来, 然后在外层查询增加筛选条件。

SELECT *
FROM (-- 第一步查询的结果
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM shopproduct AS SP
INNER JOIN product AS P
ON SP.product_id = P.product_id) AS STEP1
WHERE shop_name = ‘北京’
AND product_type = ‘衣服’;

在这里插入图片描述

我们首先给出上述查询的执行顺序:

FROM 子句 -> WHERE 子句 -> SELECT 子句

也就是说, 两张表是先按照连结列进行了连结, 得到了一张新表, 然后 WHERE 子句对这张新表的行按照两个条件进行了筛选, 最后, SELECT 子句选出了那些我们需要的列。

此外, 一种不是很常见的做法是,还可以将 WHERE 子句中的条件直接添加在 ON 子句中, 这时候 ON 子句后最好用括号将连结条件和筛选条件括起来。

SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM shopproduct AS SP
INNER JOIN product AS P
ON (SP.product_id = P.product_id
AND SP.shop_name = ‘北京’
AND P.product_type = ‘衣服’);

在这里插入图片描述

但上述这种把筛选条件和连结条件都放在 ON 子句的写法, 不是太容易阅读, 不建议大家使用。

另外, 先连结再筛选的标准写法的执行顺序是, 两张完整的表做了连结之后再做筛选,如果要连结多张表, 或者需要做的筛选比较复杂时, 在写 SQL 查询时会感觉比较吃力。在结合 WHERE 子句使用内连结的时候, 我们也可以更改任务顺序, 并采用任务分解的方法,先分别在两个表使用 WHERE 进行筛选,然后把上述两个子查询连结起来。

SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM (-- 子查询 1:从shopproduct 表筛选出东京商店的信息
SELECT *
FROM shopproduct
WHERE shop_name = ‘北京’ ) AS SP
INNER JOIN – 子查询 2:从 product 表筛选出衣服类商品的信息
(SELECT *
FROM product
WHERE product_type = ‘衣服’) AS P
ON SP.product_id = P.product_id;

在这里插入图片描述

先分别在两张表里做筛选, 把复杂的筛选条件按表分拆, 然后把筛选结果(作为表)连接起来, 避免了写复杂的筛选条件, 因此这种看似复杂的写法, 实际上整体的逻辑反而非常清晰. 在写查询的过程中, 首先要按照最便于自己理解的方式来写, 先把问题解决了, 再思考优化的问题。

练习题:

找出每个商店里的衣服类商品的名称及价格等信息:

– 参考答案 1–不使用子查询

SELECT SP.shop_id,SP.shop_name,SP.product_id
,P.product_name, P.product_type, P.purchase_price
FROM shopproduct AS SP
INNER JOIN product AS P
ON SP.product_id = P.product_id
WHERE P.product_type = ‘衣服’;

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

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

相关文章

【Java开发指南 | 第十篇】Java修饰符

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 JAVA修饰符访问修饰符非访问修饰符static 修饰符final 修饰符abstract 修饰符synchronized 修饰符transient 修饰符volatile 修饰符 JAVA修饰符 修饰符用来定义类、方法或者变量&#xff0c;通常放在语句的最前…

2024年【高处安装、维护、拆除】考试题库及高处安装、维护、拆除复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高处安装、维护、拆除考试题库是安全生产模拟考试一点通生成的&#xff0c;高处安装、维护、拆除证模拟考试题库是根据高处安装、维护、拆除最新版教材汇编出高处安装、维护、拆除仿真模拟考试。2024年【高处安装、维…

瞬态瑞丽波频散曲线提取

频散曲线 function [Y1, f, phase] = das_fft(signal1, signal2, Ts) [y, lag

windows编译xlnt,获取Excel表里的数据

用git拉取项目 这个文件是空的 要用git拉下来&#xff0c;使用终端编译xlnt库 点击解决方案 运行生成 然后新建项目&#xff0c;配置好库&#xff0c; #include <iostream> #include <xlnt/xlnt.hpp>int main() {// 打开 Excel 文件xlnt::workbook workbook;workb…

Ubuntu Vs code配置ROS开发环境

文章目录 1.开发环境2.集成开发环境搭建2.1 安装Ros2.2 安装 Vs code2.3 安装vs code 插件 3.Vs code 配置ROS3.1 创建ROS工作空间3.2 从文件夹启动Vs code3.3 使用Vscode 编译ROS 空间3.4 使用Vs code 创建功能包 4.编写简单Demo实例4.1编写代码4.2编译与执行 1.开发环境 系统…

【数学】主成分分析(PCA)的应用案例(Python)

接着上篇PCA推导过程文章&#xff0c;本文结合图像来展示PCA的应用过程 Jupyter notebook 源文件在这里 1 借助库函数来PCA重建 使用sklearn库函数 # Import needed libs import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import load_digits from…

大模型微调的几种常见方法

在文章深入理解大语言模型微调技术中&#xff0c;我们详细了解大语言模型微调的概念和训练过程&#xff0c;本篇给大家介绍大模型微调常见的7种训练方法。 1、Adapter Tuning 2019年谷歌的研究人员首次在论文《Parameter-Efficient Transfer Learning for NLP》提出针对 BERT 的…

java线程(1)

1、多线程启动 有两种启动方式 1、实现Runable接口 2、继承Thread类并且重写run&#xff08;&#xff09;方法 在执行进程中的任务才会产生线程&#xff0c;所以需要实现Runable接口并且重写run&#xff08;&#xff09;方法&#xff0c;然后将Runable的实现对象作为参数传…

(文章复现)分布式电源选址定容的多目标优化算法

参考文献&#xff1a; [1]夏澍,周明,李庚银.分布式电源选址定容的多目标优化算法[J].电网技术,2011,35(09):115-121. [2] Ye Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, “PlatEMO: A MATLAB platform for evolutionary multi-objective optimization [educational for…

图像处理与视觉感知---期末复习重点(8)

文章目录 一、图像分类流程二、梯度方向直方图2.1 概述2.2 计算梯度方向直方图2.2.1 过程2.2.2 总结 三、SIFT 一、图像分类流程 流程&#xff1a;输入图像、预处理、特征提取、学习算法、类标。 二、梯度方向直方图 2.1 概述 1. 梯度方向直方图(Histogram of Oriented Gradie…

【1688电商运营必看】掌握这些关键数据指标,轻松提升业绩!

1688电商运营&#xff0c;数据分析环节中需要关注多个关键指标&#xff0c;以便全面、深入地了解店铺或产品的运营状况。以下是一些主要的指标&#xff1a; 1、流量指标 访客数&#xff1a;反映店铺的吸引力和流量规模。 浏览量&#xff1a;显示页面的受欢迎程度&#xff0c…

【AI开发:语言】二、Qwen1.5-7B模型本地部署CPU和GPU版

前言 之前文章&#xff0c;我们采用了Koblod运行Yi-34B大模型&#xff0c;本文采用LM Studio来运行千问模型。 LM Studio并没有开源&#xff0c;但是可以免费使用&#xff0c;他是目前本地进行模型测试最好的工具了。 在这里&#xff0c;依然使用Windows 10进行部署和测试&…

GPT-3:NLP领域的革新者

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;预训练模型一直是研究的热点。随着技术的不断进步&#xff0c;我们见证了从BERT到GPT等一系列模型的涌现。其中&#xff0c;GPT-3&#xff08;Generative Pre-trained Transformer 3&#xff09;以其卓越的生成能力和…

抗干扰1路|1通道触摸单按键触摸触控ICVK3601 SOT23-6适用于玩具,风扇,台灯等触摸IC

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK3601 封装形式&#xff1a;SOT23-6 概述 VK3601具有1个触摸按键&#xff0c;可用来检测外部触摸按键上人手的触摸动作。该芯片具有较 高的集成度&#xff0c;仅需极少的外部组件便可实现触摸按键的检测。 提供了1路…

力扣周赛392复盘

3105. 最长的严格递增或递减子数组 题目 给你一个整数数组 nums 。 返回数组 nums 中 严格递增 或 严格递减 的最长非空子数组的长度。 思考&#xff1a; 返回什么&#xff1a;返回最长非空子数组的长度。return max(decs_len,incs_len); 但实际上我们只需要用一个变量ans就…

【优质书籍推荐】AI赋能100%提高项目管理效率

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

Vision GNN: An Image is Worth Graph of Nodes

感受野&#xff1a;在卷积神经网络中,感受野(Receptive Field)是指特征图上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中感受野大小区域的计算得到的。 感受野并非越大越好&#xff0c;反而可能因为过大而过于发散梯度下降&#xff08;Gradient Descent GD&am…

在linux系统中启动pycharm

1.找到pycharm的安装路径&#xff0c;一般在下载文件夹中 2.进入pycharm的安装路径&#xff0c;进入bin目录 3.右击&#xff0c;打开终端&#xff0c;输入./pycharm.sh

民航电子数据库:[E14024]事务内变更操作次数超过最大许可值10000,可通过系统参数max_trans_modify适当调整限制

目录 一、场景二、异常情况三、原因四、排查五、解决 一、场景 1、对接民航电子数据 2、执行delete语句时报错 二、异常情况 三、原因 通过报错信息就可以看出&#xff0c;是系统参数max_trans_modify配置导致 当删除的数据量 > max_trans_modify时&#xff0c;删除就会…

【LeetCode每日一题】924. 尽量减少恶意软件的传播(并查集)

文章目录 [924. 尽量减少恶意软件的传播](https://leetcode.cn/problems/minimize-malware-spread/)思路&#xff1a;并查集代码&#xff1a; 924. 尽量减少恶意软件的传播 思路&#xff1a;并查集 构建并查集&#xff1a;首先&#xff0c;代码创建了一个 UnionFind 类来维护节…