【用于数据分析的 SQL(二)】【SQL JOINS】

本文深入探讨了SQL中的JOIN语句,介绍了如何通过JOIN从多个表中提取数据,并详细讲解了简单JOIN、复杂JOIN及高级JOIN的应用场景和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇:【用于数据分析的 SQL(一)】【基本SQL】

一、 前言

将学习如何将多个表的数据组合起来

二、 数据库规范化

创建数据库时,考虑如何存储数据非常重要。这被称为规范化,它是大多数SQL类的重要组成部分。如果你负责建立一个新的数据库,重要的是要有一个数据库正常化的透彻理解。

主要有三种想法旨在实现数据库规范化:
1.表是存储数据的逻辑分组吗?
2.可以在单个位置进行更改,而不是在许多表中更改相同的信息吗?
3.可以快速高效地访问和操作数据吗?

三、 简介

JOIN语句的全部目的是允许我们一次从多个表中提取数据。

同样-JOINs 有助于我们从多个表中提取数据。这既简单又强大。

随着JOIN声明添加到我们的工具包中,我们还将添加ON语句。

我们使用ON条款来指定JOIN条件,这是一个合乎逻辑的语句,将表和语句组合在一起。

四、 简单的JOIN

1.从帐户表中提取所有数据,以及从订单表中提取所有数据

SELECT orders.*, accounts.*
FROM accounts
JOIN orders
ON accounts.id = orders.account_id;

2.从订单表中提取standard_qty、gloss_qty和poster_qty,从帐户表中提取网站和primary_poc。

SELECT orders.standard_qty, orders.gloss_qty, 
       orders.poster_qty,  accounts.website, 
       accounts.primary_poc
FROM orders
JOIN accounts
ON orders.account_id = accounts.id

五、 key

主键 (PK)
主键是特定表中唯一的列。这是我们每个表格中的第一个列。在这里,这些列都称为ID,但不一定必须是名称。在大多数数据库中,主键是我们表中的第一列,这很常见。

外国密钥 (FK)
外国密钥是一个表中的列,该列是另一个表中的主要密钥。

每个都链接到另一个表的主键。

在这里插入图片描述
主要 - 外国密钥链接
在上图中,您可以看到:

region_id是外国的关键。
region_id链接到 ID - 这是连接这两个表的主要外国密钥链接。
乌鸦的脚显示,FK实际上可以出现在sales_reps表的许多行。
虽然单行告诉我们PK显示 ID 在此表中每行只显示一次。

六、 复杂的JOIN

在这里插入图片描述
1.为与帐户名称关联的所有web_events提供一张表格。应该有三列。请务必包括事件的时间、每个事件的时间。此外,您可能选择添加第四个列,以确保只选择事件。

SELECT a.primary_poc, w.occurred_at, w.channel, a.name
FROM web_events w
JOIN accounts a
ON w.account_id = a.id
WHERE a.name = 'Walmart';

2.提供一张表格,为每个sales_rep及其关联帐户提供区域。您的最终表应包括三个列:区域名称、销售代表名称和帐户名称。根据帐户名称按字母顺序对帐户(A-Z)进行排序。

SELECT r.name region, s.name rep, a.name account
FROM sales_reps s
JOIN region r
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
ORDER BY a.name;

3.为每个订单提供每个区域的名称,以及他们为订单支付的帐户名称和单价(total_amt_usd/总计)。您的最终表应有 3 列:区域名称、帐号和单价。有几个帐户总共有0,所以我除以(总计+0.01),以确保不除以零。

SELECT r.name region, a.name account, 
       o.total_amt_usd/(o.total + 0.01) unit_price
FROM region r
JOIN sales_reps s
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id;

七、 究极的JOIN

在这里插入图片描述

1.提供一张表格,为每个sales_rep及其关联帐户提供区域。这次只针对该地区。您的最终表应包括三个列:区域名称、销售代表名称和帐户名称。根据帐户名称按字母顺序对帐户(A-Z)进行排序。

SELECT r.name region, s.name rep, a.name account
FROM sales_reps s
JOIN region r
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
WHERE r.name = 'Midwest'
ORDER BY a.name;

2.提供一张表格,为每个sales_rep及其关联帐户提供区域。这一次仅针对销售代表以该区域开头和所在区域中具有名字的帐户。您的最终表应包括三个列:区域名称、销售代表名称和帐户名称。根据帐户名称按字母顺序对帐户(A-Z)进行排序。

SELECT r.name region, s.name rep, a.name account
FROM sales_reps s
JOIN region r
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
WHERE r.name = 'Midwest' AND s.name LIKE 'S%'
ORDER BY a.name;

3.提供一张表格,为每个sales_rep及其关联帐户提供区域。这一次仅针对销售代表以该区域开始和在该地区的姓氏的帐户。您的最终表应包括三个列:区域名称、销售代表名称和帐户名称。根据帐户名称按字母顺序对帐户(A-Z)进行排序。

SELECT r.name region, s.name rep, a.name account
FROM sales_reps s
JOIN region r
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
WHERE r.name = ‘Midwest’ AND s.name LIKE ‘% K%’
ORDER BY a.name;

4.为每个订单提供每个区域的名称,以及他们为订单支付的帐户名称和单价(total_amt_usd/总计)。但是,您只应在标准订单数量超过时提供结果。您的最终表应有 3 列:区域名称、帐号和单价。

SELECT r.name region, a.name account, o.total_amt_usd/(o.total + 0.01) unit_price
FROM region r
JOIN sales_reps s
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id
WHERE o.standard_qty > 100;

5.为每个订单提供每个区域的名称,以及他们为订单支付的帐户名称和单价(total_amt_usd/总计)。但是,您只应在标准订单数量超过和海报订单数量超过时提供结果。您的最终表应有 3 列:区域名称、帐号和单价。首先对最小的单价进行排序。

SELECT r.name region, a.name account, o.total_amt_usd/(o.total + 0.01) unit_price
FROM region r
JOIN sales_reps s
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id
WHERE o.standard_qty > 100 AND o.poster_qty > 50
ORDER BY unit_price;

6.为每个订单提供每个区域的名称,以及他们为订单支付的帐户名称和单价(total_amt_usd/总计)。但是,您只应在标准订单数量超过和海报订单数量超过时提供结果。您的最终表应有 3 列:区域名称、帐号和单价。首先为最大的单价排序。

SELECT r.name region, a.name account, o.total_amt_usd/(o.total + 0.01) unit_price
FROM region r
JOIN sales_reps s
ON s.region_id = r.id
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id
WHERE o.standard_qty > 100 AND o.poster_qty > 50
ORDER BY unit_price DESC;

7.帐户 ID使用的不同通道是什么?您的最终表应只有2列:帐户名称和不同的通道。您可以尝试选择"选择",将结果缩小到只有唯一的值。

SELECT DISTINCT a.name, w.channel
FROM accounts a
JOIN web_events w
ON a.id = w.account_id
WHERE a.id = '1001';

8.查找所有发生的订单。您的最终表应有 4 列:occurred_at、帐号、订单总数和订单total_amt_usd。

SELECT o.occurred_at, a.name, o.total, o.total_amt_usd
FROM accounts a
JOIN orders o
ON o.account_id = a.id
WHERE o.occurred_at BETWEEN '01-01-2015' AND '01-01-2016'
ORDER BY o.occurred_at DESC;

下一篇:【用于数据分析的 SQL(三)】【SQL 聚合】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值