SQL子查询入门指南


子查询是SQL中用于处理复杂数据操作的常用工具。如果你是正在学习子查询的新手,那么这篇文章正适合你!


SQL中的子查询并非神秘难懂,正如你将在本教程中看到的那样。它们是简化复杂数据任务、提高复杂查询可读性以及进行高级数据操作的非常有用的工具。

如果你不想停留在SQL的基础层面,子查询是必不可少的技能。


什么是SQL中的子查询?

子查询(Subquery)——或称内层查询(Inner Query)——是嵌套在另一个SQL语句中的SELECT语句,后者被称为外层查询或主查询(Outer Query/Main Query)。

在SQL中,子查询通常用于以下语句/子句中:

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • WHERE
  • HAVING
  • FROM
  • SET

SQL子查询的类型

子查询通常分为四种类型。在大多数情况下,子查询用于在WHEREHAVING子句中筛选数据,或在FROM中创建派生表。

以下是四种子查询类型的详细概述以及它们的常见应用场景:


SQL子查询实战

接下来,我们将通过每种子查询类型的实际示例来进行讲解。


1. 使用单行子查询筛选数据

任务:Yelp要求你找到“获得最多‘酷’票数的评论文本”。输出应包含商户名称评论文本

解决方案:我们可以使用单行子查询来实现。该子查询计算出‘酷’票数的最大值(单个值,因此是单行子查询),并将其放在主查询的WHERE子句中,只输出符合条件的商户和评论文本。

SELECT business_name,
       review_text
FROM yelp_reviews
WHERE cool =
    (SELECT MAX(cool)
     FROM yelp_reviews);

输出:
只包含获得最多‘酷’票数的商户和评论文本。


2. 使用多行子查询筛选数据

任务:Twitter和Asana的面试问题,要求找到“每个部门薪资最高的员工”。输出应包含部门员工姓名薪资

解决方案:我们可以使用多行子查询来完成。

  • 外层查询输出所需的列,子查询通过WHEREIN筛选数据。
  • 子查询使用MAX()找到最高薪资。为了按部门计算最大值,需要在SELECTGROUP BY中包含部门列。
SELECT department AS department,
       first_name AS employee_name,
       salary
FROM employee
WHERE (department, salary) IN
        (SELECT department, 
                MAX(salary)
        FROM employee         
        GROUP BY department
        );

输出:
每个部门薪资最高的员工及其薪资。


3. 使用相关子查询筛选数据

相关子查询是一种特殊的子查询类型,它在执行时依赖于外层查询的值。我们将重写上一个例子,改用相关子查询:

SELECT department AS department,
       first_name AS employee_name,
       salary
FROM employee AS oq
WHERE salary = (
    SELECT MAX(sq.salary)
    FROM employee AS sq
    WHERE sq.department = oq.department
);

解释:

  • 外层查询中,给employee表起别名oq(表示“外层查询”)。
  • WHERE子句中,我们将薪资与子查询的结果进行比较。
  • 子查询中再次从employee表获取数据,并起别名为sq(表示“子查询”)。MAX()计算最高薪资,并通过WHERE条件确保对每个部门分别计算。

输出:
结果与多行子查询相同。


4. 使用嵌套查询创建派生表

任务:Forbes要求你找到“全球利润最高的三家公司”,并满足以下要求:

  1. 按利润降序排列;
  2. 利润相同的公司拥有相同排名,并全部包含在输出中;
  3. 输出包含公司名称利润值

解决方案:我们使用两个子查询:

  1. 第二层子查询计算每家公司的总利润。
  2. 第一层子查询对公司按利润排名。
  3. 外层查询则根据排名筛选前3家公司。
SELECT company,
       profit
FROM
  (SELECT *,
          DENSE_RANK() OVER (ORDER BY profit DESC) AS rank
   FROM
     (SELECT company,
             SUM(profits) AS profit
      FROM forbes_global_2010_2014
      GROUP BY company) sq) sq2
WHERE rank <=3;

解释:

  • 第二层子查询计算公司总利润,并命名为sq
  • 第一层子查询使用DENSE_RANK()窗口函数对公司按利润降序排名,命名为sq2
  • 外层查询筛选排名为1到3的公司,并输出公司名称和利润。

输出:
全球利润最高的三家公司及其利润。


总结

本文是SQL子查询的入门指南,旨在为初学者提供一个良好的起点。我们介绍了四种主要的子查询类型,并通过实际示例讲解了它们的应用。

通过掌握这些基础知识,你可以编写自己的SQL子查询,提高数据操作技能,并更深入地学习SQL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值