SQL 数据科学:了解和利用联接

推荐:使用 NSDT场景编辑器助你快速搭建可编辑的3D应用场景

什么是 SQL 中的连接?

SQL 联接允许您基于公共列合并来自多个数据库表的数据。这样,您就可以将信息合并在一起,并在相关数据集之间创建有意义的连接。

SQL 中的连接类型

有几种类型的 SQL 联接:

  • 内联接
  • 左外连接
  • 右外连接
  • 完全外部联接
  • 交叉连接

让我们解释每种类型。

SQL 内部联接

内部联接仅返回在要联接的两个表中存在匹配项的行。它基于共享键或列合并两个表中的行,丢弃不匹配的行。

我们通过以下方式对此进行可视化。

SQL 数据科学:了解和利用联接

在 SQL 中,这种类型的连接是使用关键字 JOIN 或 INNER JOIN 执行的。

SQL 左外部联接

左外连接返回左侧(或第一个)表中的所有行和右侧(或第二个)表中的匹配行。如果没有匹配项,则返回右侧表中列的 NULL 值。

我们可以这样想象它。

SQL 数据科学:了解和利用联接

如果要在 SQL 中使用此联接,可以使用 LEFT OUTER JOIN 或 LEFT JOIN 关键字来实现。这是一篇讨论左联接与左外联接的文章。

SQL 右外联接

右联接与左联接相反。它返回右侧表中的所有行和左侧表中的匹配行。如果没有匹配项,则返回左侧表中列的 NULL 值。

SQL 数据科学:了解和利用联接

在 SQL 中,此连接类型是使用关键字 RIGHT OUTER JOIN 或 RIGHT JOIN 执行的。

SQL 完全外部联接

完全外部联接返回两个表中的所有行,尽可能匹配行,并为不匹配的行填充 NULL 值。

SQL 数据科学:了解和利用联接

SQL 中此联接的关键字是“完全外部联接”或“完全联接”。

SQL 交叉联接

这种类型的联接将一个表中的所有行与第二个表中的所有行合并在一起。换句话说,它返回笛卡尔积,即两个表行的所有可能组合。

这是可视化效果,使其更容易理解。

SQL 数据科学:了解和利用联接

在 SQL 中交叉联接时,关键字是 CROSS JOIN。

了解 SQL 联接语法

要在 SQL 中执行联接,您需要指定要联接的表、用于匹配的列以及要执行的联接类型。在 SQL 中联接表的基本语法如下:

SELECT columns
FROM table1
JOIN table2
ON table1.column = table2.column;

此示例演示如何使用 JOIN。

引用 FROM 子句中的第一个(或左侧)表。然后,使用 JOIN 跟随它并引用第二个(或右侧)表。

然后是 ON 子句中的连接条件。您可以在此处指定将用于联接两个表的列。通常,它是一个共享列,它是一个表中的主键和第二个表中的外键。

注意:主键是表中每条记录的唯一标识符。外键在两个表之间建立链接,即它是第二个表中引用第一个表的列。我们将在示例中向您展示这意味着什么。

如果你想使用左联接、右联接或完全联接,你只需使用这些关键字而不是 JOIN ——代码中的其他一切都完全相同!

交叉连接的情况略有不同。其性质是联接两个表中的所有行组合。这就是为什么不需要 ON 子句,语法如下所示。

SELECT columns
FROM table1
CROSS JOIN table2;

换句话说,您只需在 FROM 中引用一个表,在 CROSS JOIN 中引用第二个表。

或者,您可以在 FROM 中引用这两个表并用逗号分隔它们 - 这是 CROSS JOIN 的简写。

SELECT columns
FROM table1, table2;

自连接:SQL 中一种特殊类型的连接

还有一种连接表的特定方法 - 将表与自身连接。这也称为自联表。

它不完全是一种独特的联接类型,因为前面提到的任何联接类型也可用于自联接。

自联接的语法与我之前向您展示的语法类似。主要区别在于 FROM 和 JOIN 中引用了相同的表。

SELECT columns
FROM table1 t1
JOIN table1 t2
ON t1.column = t2.column;

此外,您需要为表提供两个别名以区分它们。您正在做的是将表与自身联接,并将其视为两个表。

我只是想在这里提到这一点,但我不会进一步详细介绍。如果您对自加入感兴趣,请参阅这本关于 SQL 中自加入的图解指南。

SQL 联接示例

是时候向您展示我提到的所有内容在实践中是如何工作的了。我将使用 StrataScratch 中的 SQL JOIN 面试问题来展示 SQL 中每种不同类型的连接。

1. 连接示例

Microsoft的这个问题希望您列出每个项目并按员工计算项目的预算。

昂贵的项目

“给定映射到每个项目的项目和员工列表,按分配给每个员工的项目预算金额计算。输出应包括项目标题和项目预算,四舍五入到最接近的整数。首先按每位员工预算最高的项目对列表进行排序。

数据

这个问题给出了两个表格。

ms_projects

编号:国际
标题:瓦尔查尔
预算:国际

ms_emp_projects

emp_id:国际
project_id:国际

现在,表 ms_projects 中的列 id 是表的主键。可以在表ms_emp_projects中找到相同的列,尽管名称不同:project_id。这是表的外键,引用第一个表。

我将使用这两列来联接解决方案中的表。

法典

SELECT title AS project,
       ROUND((budget/COUNT(emp_id)::FLOAT)::NUMERIC, 0) AS budget_emp_ratio
FROM ms_projects a
JOIN ms_emp_projects b 
ON a.id = b.project_id
GROUP BY title, budget
ORDER BY budget_emp_ratio DESC;

我使用 JOIN 连接了两个表。表 ms_projects 在 FROM 中引用,而ms_emp_projects在 JOIN 之后引用。我为两个表提供了一个别名,这样我以后就不会使用该表的长名称。

现在,我需要指定要联接表的列。我已经提到哪些列是一个表中的主键,哪些列是另一个表中的外键,所以我将在这里使用它们。

我相等这两列,因为我想获取项目 ID 相同的所有数据。我还在每列前面使用了表的别名。

现在我可以访问两个表中的数据,我可以在 SELECT 中列出列。第一列是项目名称,第二列是计算的。

此计算使用 COUNT() 函数来计算每个项目的员工人数。然后,我将每个项目的预算除以员工人数。我还将结果转换为十进制值并将其四舍五入到零小数位。

输出

下面是查询返回的内容。

SQL 数据科学:了解和利用联接

2. 左连接示例

让我们在Airbnb面试问题上练习这个加入。它希望您找到每个城市的订单数量、客户数量和订单总成本。

客户订单和详细信息

“查找每个城市的订单数量、客户数量和订单总成本。仅包括至少下了 5 个订单的城市,并计算每个城市的所有客户,即使他们没有下订单。

输出每个计算以及相应的城市名称。

数据

您将获得客户和订单的表格。

客户

编号:国际
first_name:瓦尔查尔
last_name:瓦尔查尔
城市:瓦尔查尔
地址:瓦尔查尔
phone_number:瓦尔查尔

订单

编号:国际
cust_id:国际
order_date:日期时间
order_details:瓦尔查尔
total_order_cost:国际

共享列是来自表客户的 id,cust_id来自表订单。我将使用这些列来联接表。

法典

以下是使用左联接解决此问题的方法。

SELECT c.city,
       COUNT(DISTINCT o.id) AS orders_per_city,
       COUNT(DISTINCT c.id) AS customers_per_city,
       SUM(o.total_order_cost) AS orders_cost_per_city
FROM customers c
LEFT JOIN orders o ON c.id = o.cust_id
GROUP BY c.city
HAVING COUNT(o.id) >=5;

我在 FROM(这是我们的左表)中引用表客户,并在客户 ID 列上将其与订单左连接。

现在我可以选择城市,使用 COUNT() 按城市获取订单和客户数量,并使用 SUM() 按城市计算总订单成本。

为了按城市获得所有这些计算,我按城市对输出进行分组。

问题中还有一个额外的要求:“仅包括至少下了 5 个订单的城市......”我使用“必须”仅显示具有五个或更多订单的城市来实现此目的。

问题是,为什么我使用了 LEFT JOIN 而不是 JOIN?线索在问题中:“...并计算每个城市的所有客户,即使他们没有下订单。可能并非所有客户都下了订单。这意味着我想显示表客户中的所有客户,这完全符合左连接的定义。

如果我使用 JOIN,结果将是错误的,因为我会错过没有下任何订单的客户。

注意:SQL 中连接的复杂性并不反映在它们的语法上,而是反映在它们的语义上! 如您所见,每个联接的编写方式相同,只是关键字发生了变化。但是,每个联接的工作方式不同,因此可以根据数据输出不同的结果。因此,您必须完全了解每个联接的作用,并选择能够准确返回您想要的联接!

输出

现在,让我们看一下输出。

SQL 数据科学:了解和利用联接

3. 右连接示例

右联接是左联接的镜像。这就是为什么我可以使用RIGHT JOIN轻松解决之前的问题。让我告诉你怎么做。

数据

表格保持不变;我将只使用不同类型的联接。

法典

SELECT c.city,
       COUNT(DISTINCT o.id) AS orders_per_city,
       COUNT(DISTINCT c.id) AS customers_per_city,
       SUM(o.total_order_cost) AS orders_cost_per_city
FROM orders o
RIGHT JOIN customers c ON o.cust_id = c.id 
GROUP BY c.city
HAVING COUNT(o.id) >=5;

以下是更改的内容。当我使用 RIGHT JOIN 时,我切换了表的顺序。现在,表订单变为左订单,表客户订单变为右侧订单。连接条件保持不变。我只是切换了列的顺序以反映表的顺序,但没有必要这样做。

通过切换表的顺序并使用 RIGHT JOIN,我将再次输出所有客户,即使他们没有下任何订单。

查询的其余部分与上一示例中相同。输出也是如此。

注意:在实践中,右联接相对较少使用。对于SQL用户来说,LEFT JOIN似乎更自然,因此他们更频繁地使用它。任何可以用 RIGHT JOIN 完成的事情也可以用 LEFT JOIN 完成。因此,没有特定情况可能首选 RIGHT JOIN。

输出

SQL 数据科学:了解和利用联接

4. 完全连接示例

Salesforce和特斯拉的问题希望你计算2020年推出的产品公司数量与前一年推出的产品公司数量之间的净差异。

新产品

“你会得到一个按公司按年份列出的产品发布表。编写一个查询来计算 2020 年推出的产品公司数量与上一年推出的产品公司数量之间的净差额。输出公司名称以及与上一年相比发布的2020年净产品净差额。

数据

该问题提供了一个包含以下列的表。

car_launches

年:国际
company_name:瓦尔查尔
product_name:瓦尔查尔

当只有一个表时,我将如何连接表?嗯,让我们也看看吧!

法典

这个查询有点复杂,所以我会逐渐揭示它。

SELECT company_name,
       product_name AS brand_2020
FROM car_launches
WHERE YEAR = 2020;

第一个 SELECT 语句查找 2020 年的公司和产品名称。此查询稍后将转换为子查询。

这个问题希望你找到2020年和2019年之间的区别。因此,让我们为2019年编写相同的查询。

SELECT company_name,
       product_name AS brand_2019
FROM car_launches
WHERE YEAR = 2019;

现在,我将把这些查询变成子查询,并使用完全外部联接来联接它们。

SELECT *
FROM
  (SELECT company_name,
          product_name AS brand_2020
   FROM car_launches
   WHERE YEAR = 2020) a
FULL OUTER JOIN
  (SELECT company_name,
          product_name AS brand_2019
   FROM car_launches
   WHERE YEAR = 2019) b 
ON a.company_name = b.company_name;

子查询可以被视为表,因此可以连接。我给第一个子查询一个别名,并将其放在 FROM 子句中。然后,我使用“完全外部联接”将其与公司名称列上的第二个子查询联接。

通过使用这种类型的 SQL 联接,我将在 2020 年的所有公司和产品与 2019 年的所有公司和产品合并。

SQL 数据科学:了解和利用联接

现在我可以完成我的查询了。让我们选择公司名称。此外,我将使用 COUNT() 函数查找每年推出的产品数量,然后减去它以获得差额。最后,我将按公司对输出进行分组,并按公司字母顺序对其进行排序。

这是整个查询。

SELECT a.company_name,
       (COUNT(DISTINCT a.brand_2020)-COUNT(DISTINCT b.brand_2019)) AS net_products
FROM
  (SELECT company_name,
          product_name AS brand_2020
   FROM car_launches
   WHERE YEAR = 2020) a
FULL OUTER JOIN
  (SELECT company_name,
          product_name AS brand_2019
   FROM car_launches
   WHERE YEAR = 2019) b 
ON a.company_name = b.company_name
GROUP BY a.company_name
ORDER BY company_name;

输出

以下是 2020 年和 2019 年之间的公司列表和推出的产品差异。

SQL 数据科学:了解和利用联接

5. 交叉连接示例

德勤的这个问题非常适合展示CROSS JOIN的工作原理。

最多两个数字

“给定一列数字,考虑两个数字的所有可能排列,假设数字对(x,y)和(y,x)是两个不同的排列。然后,对于每个排列,找到两个数字中的最大值。

输出三列:第一列、第二个数字和两列中的最大值。

该问题希望您找到两个数字的所有可能排列,假设数字对 (x,y) 和 (y,x) 是两个不同的排列。然后,我们需要找到每个排列的最大值。

数据

这个问题给了我们一个带有一列的表格。

deloitte_numbers

数:国际

法典

此代码是 CROSS JOIN 的一个示例,也是自连接的示例。

SELECT dn1.number AS number1,
       dn2.number AS number2,
       CASE
           WHEN dn1.number > dn2.number THEN dn1.number
           ELSE dn2.number
       END AS max_number
FROM deloitte_numbers AS dn1
CROSS JOIN deloitte_numbers AS dn2;

我在 FROM 中引用该表并给它一个别名。然后,我通过在交叉连接后引用它并为表提供另一个别名来将其与自身交叉连接。

现在可以使用一个表,因为它们是两个。我从每个表中选择列号。然后,我使用 CASE 语句设置一个条件,该条件将显示两个数字的最大数量。

为什么在这里使用交叉连接?请记住,它是一种 SQL 联接类型,将显示所有表中所有行的所有组合。这正是问题要问的!

输出

这是所有组合的快照以及两者的较高数字。

SQL 数据科学:了解和利用联接

将 SQL 联接用于数据科学

现在您已经知道如何使用 SQL 联接,问题是如何在数据科学中利用这些知识。

SQL 联接在数据科学任务(如数据浏览、数据清理和特征工程)中起着至关重要的作用。

下面是如何利用 SQL 联接的几个示例:

  1. 合并数据:通过联接表,可以将不同的数据源汇集在一起,从而分析多个数据集之间的关系和相关性。例如,将客户表与交易表联接可以提供对客户行为和购买模式的见解。
  1. 数据验证:联接可用于验证数据质量和完整性。通过比较来自不同表的数据,可以识别不一致、缺失值或异常值。这有助于您进行数据清理,并确保用于分析的数据准确可靠。
  1. 特征工程:联接有助于为机器学习模型创建新功能。通过合并相关表,您可以提取有意义的信息并生成捕获数据中重要关系的特征。这可以增强模型的预测能力。
  1. 聚合和分析:联接使您能够跨多个表执行复杂的聚合和分析。通过组合来自各种来源的数据,您可以全面了解数据并获得有价值的见解。例如,将销售表与产品表联接可以帮助您按产品类别或区域分析销售业绩。

SQL 联接的最佳做法

正如我已经提到的,联接的复杂性并没有体现在它们的语法中。您看到语法相对简单。

联接的最佳实践也反映了这一点,因为它们不关心编码本身,而是联接的作用和性能。

若要充分利用 SQL 中的联接,请考虑以下最佳做法。

  1. 了解您的数据: 熟悉数据中的结构和关系。这将帮助您选择适当的联接类型,并选择正确的列进行匹配。
  1. 使用索引:如果表很大或经常联接,请考虑在用于联接的列上添加索引。索引可以显著提高查询性能。
  1. 注意性能:联接大型表或多个表的计算成本可能很高。通过筛选数据、使用适当的联接类型并考虑使用临时表或子查询来优化查询。
  1. 测试和验证:始终验证联接结果以确保正确性。执行健全性检查并验证联接的数据是否符合您的预期和业务逻辑。

结论

SQL 联接是一个基本概念,使数据科学家能够合并和分析来自多个源的数据。通过了解不同类型的 SQL 联接、掌握其语法并有效利用它们,数据科学家可以解锁有价值的见解、验证数据质量并推动数据驱动的决策。

我用五个例子向您展示了如何做到这一点。现在,您可以利用 SQL 的强大功能并加入您的数据科学项目并取得更好的结果。

原文链接:SQL 数据科学:了解和利用联接 (mvrlink.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

积木报表集成前端加载js文件404

项目场景: 在集成积木报表和shiro时候: 集成积木报表,shrio,shrio是定义在另一个模块下的,供另一个启动类使用,积木报表集成shrio的时候,需要依赖存放shrio的核心包,该核心包除了存…

Eleastisearch5.2.2利用镜像迁移构建实例后ES非健康状态

正常迁移完成后启动服务,查看ES非健康状态 此时观察ES集群状态:curl -XGET -u elastic:xxx localhost:9200/_cluster/health?pretty 注意到"active_shards_percent_as_number" : 88.8888 该项的值不产生变化;集群状态"status" : “…

常见的数据结构(顺序表、顺序表、链表、栈、队列、二叉树)

线性表(Linear List)  1.什么是线性表 2.线性表的特点 3.线性表的基本运算 顺序表 1.什么是顺序表 2.时间复杂度: 链表 1.什么是链表 2.单向链表 3. 双向链表 4.ArrayList和LinkedList的使用 栈Stack  1.什么是栈  2.栈的基本方法 队列…

【果树农药喷洒机器人】Part2:机器人变量喷药系统硬件选型

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

【ChatGPT 指令大全】怎么使用ChatGPT辅助程式开发

目录 写程式 解读程式码 重构程式码 解 bug 写测试 写 Regex 总结 在当今快节奏的数字化世界中,程式开发变得越来越重要和普遍。无论是开发应用程序、网站还是其他软件,程式开发的需求都在不断增长。然而,有时候我们可能会遇到各种问题…

C语言数据类型

C语言具有多种数据类型,用于存储不同类型的数据。大体可以分为基本数据类型和派生数据类型两大类。 一、基本数据类型 整型(Integer): 用于表示整数值,包括int、short、long和long long等类型,可以有不同…

AI:03-基于深度神经网络的低空无人机目标检测图像识别的研究

文章目录 数据集收集与预处理深度神经网络模型设计模型训练与优化目标检测与图像识别代码实现:实验结果与分析讨论与展望低空无人机的广泛应用为许多领域带来了巨大的潜力和机会。为了实现无人机的自主导航和任务执行,准确的目标检测和图像识别是至关重要的。本文旨在研究并提…

软件外包开发的VUE开发框架

Vue.js(通常简称为Vue)是一个流行的渐进式JavaScript框架,用于构建用户界面。它的核心库专注于视图层,但也可以结合其他库和工具来构建完整的单页面应用(SPA)。以下分享Vue.js的开发框架和特点,…

剑指offer-1.1C++

sizeof空类问题 问:定义一个空的类型,里面没有任何成员变量和成员函数。对该类型求sizeof,得到的结果是多少? 答:1 问:为什么不是0? 答:空类型的实例中不包含任何信息&#xff0…

小说推文怎么做详细教程。小说推文项目拆解及分享

科思创业汇 大家好,这里是科思创业汇,一个轻资产创业孵化平台。赚钱的方式有很多种,我希望在科思创业汇能够给你带来最快乐的那一种! 如何制作小说推文的详细教程! 我做自媒体已经五年了,在自媒体行业也…

STM32CubeMX之freeRTOS消息队列

创建一个消息队列,两个发送任务,一个接受任务 发送任务一:等待时间为0 发送任务二:等待时间为最大 接受为0 简单来说就是: 任务一:一个普写 一个死写 一个普读 任务二:创造队列 一个普写 …

什么是React?React与VU的优缺点有哪些?

什么是React?什么是VUE? 维基百科上的概念解释,Vue.js是一个用于创建用户界面的开源MVVM前端JavaScript框架,也是一个创建单页应用的Web应用框架。Vue.js由尤雨溪(Evan You)创建,由他和其他活跃…

Scractch3.0_Arduino_ESP32_学习随记_IO中断(六)

IO中断 目的器材程序联系我们 目的 ESP32 IO中断的使用。 中断: 当IO中断事件发生时,MCU将优先执行中断的程序。 打个比方: 你正在读一本书,突然手机收到一条紧急消息。你不想错过这个重要的消息,所以你立即停下手中的…

MySQL高阶知识点

MySQL 文章目录 MySQLchar和varchar的区别视图视图的特点 存储过程存储过程的特点 触发器触发器的特点 MySQL引擎索引为什么要有索引呢?什么是索引索引的优势索引的劣势索引类型索引种类组合索引最左前缀原则索引创建原则B树和B树的区别数据库为什么使用B树而不是B树…

伪类和伪元素有何区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 伪类(Pseudo-class)⭐ 伪元素(Pseudo-element)⭐ 区别总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前…

原始套接字编程(AF_PACKET+SOCK_RAW)模拟一个PING

1. 背景 最近看一个客户的代码片段,发现他在用原始套接字编程,一般学习套接字都是流式套接字和数据报套接字,本来也不是搞网络的,原始套接字了解得很少,借着这次机会,自己来学习一下原始套接字编程。 2. …

Nevron Vision for .NET Crack

Nevron Vision for .NET Crack NET Vision是一个用于创建具有数据可视化功能的强大数据表示应用程序的套件。该套件具有用于.NET的Nevron Chart、用于.NET的Nevron Diagram和用于.NET的Nevron User Interface。精心设计的对象模型、众多功能和高质量的演示使复杂数据的可视化变…

IntelliJ IDEA如何重新弹出git身份验证窗口

1、点击File菜单—>点击Settings—>点击Appearance & Behavior—>点击System Settings—>点击Passwords—>选中Do not save, forget passwords after restart—>点击Apply—>点击OK,如下所示: 2、重启IntelliJ IDEA—>通过g…

若依管理系统后端将 Mybatis 升级为 Mybatis-Plus

文章目录 说明流程增加依赖修改配置文件注释掉MybatisConfig里面的Bean 代码生成使用IDEA生成代码注意 Controller文件 说明 若依管理系统是一个非常完善的管理系统模板,里面含有代码生成的方法,可以帮助用户快速进行开发,但是项目使用的是m…

Linux 编译CEF源码详细记录

Linux CEF(Chromium Embedded Framework)源码下载编译 背景 由于CEF默认的二进制分发包不支持音视频播放,需要自行编译源码,将ffmpeg开关打开才能支持。这里介绍的是Linux平台下的CEF源码下载编译过程。 Windows平台参考&#…