当前位置:首页 > 问答 > 正文

数据库子查询怎么用?实例讲解和常见例子分享,帮你快速理解子查询操作

当我们使用数据库时,有时候一个简单的查询语句无法直接得到我们想要的结果,我们需要先查一个东西,然后用这个查出来的结果再去查另一个东西,这个“在一个查询语句里面嵌套另一个查询语句”的操作,就叫做子查询,你可以把它想象成“套娃”查询。

子查询到底是什么?

子查询就是充当“助手”的查询,它先执行,然后把它的查询结果交给“主”查询去使用,这个“助手”查询被包裹在括号里,可以出现在SQL语句的很多地方,SELECTFROMWHEREHAVING 这些关键字的后面。

子查询怎么用?来看几个接地气的例子

假设我们有两张表,一张是员工表,里面有员工的ID、姓名、部门和工资;另一张是部门表,里面有部门的ID和部门名称。

例子1:找出比公司平均工资高的员工(用在WHERE后面)

这是我们最常遇到的场景,我们想知道哪些员工的工资超过了全公司的平均水平。

思路是:我们需要一个“助手”(子查询)去算出公司的平均工资是多少,主查询拿每个员工的工资去和这个算出来的平均数比较。

SQL语句会是这样:

SELECT 姓名, 工资
FROM 员工表
WHERE 工资 > (
    SELECT AVG(工资) FROM 员工表  -- 这个子查询先执行,返回一个数字,比如8000
);

括号里的 SELECT AVG(工资) FROM 员工表 就是子查询,数据库会先执行它,得到平均工资(假设是8000元),主查询就变成了一个非常简单的查询:SELECT 姓名, 工资 FROM 员工表 WHERE 工资 > 8000

例子2:找出每个部门工资最高的员工(用在FROM后面)

这个需求稍微复杂一点,我们想要的结果是:看到部门名称,以及该部门最高工资是多少。

思路是:我们可以先用一个“助手”查询,按部门分组,找出每个部门的最高工资,这个查询结果本身就像一张临时的新表(有部门ID和最高工资两个字段),我们的主查询就从这张“临时表”和原始的部门表里取数据,把部门ID对应起来,显示出部门的名称。

SQL语句会是这样:

SELECT d.部门名称, t.最高工资
FROM 部门表 d
JOIN (
    SELECT 部门ID, MAX(工资) AS 最高工资  -- 这个子查询生成一张临时表t
    FROM 员工表
    GROUP BY 部门ID
) t ON d.部门ID = t.部门ID;

这里的 (SELECT ... GROUP BY 部门ID) 这个子查询是跟在 FROM ... JOIN 后面的,它先执行,生成一个临时的、虚拟的表(我们给它起了个别名叫t),里面存着每个部门及其最高工资,然后主查询就把部门表和这个临时表t连接起来,最终得到我们想要的结果。

例子3:检查是否存在某个条件的员工(用在EXISTS后面)

有时候我们关心的不是具体数据,而是“有没有”的问题,我们想找出“存在员工的”部门有哪些。

思路是:对于部门表里的每一个部门,我们让“助手”去员工表里检查一下,看看有没有员工的部门ID和这个部门的ID匹配,只要找到一个,就说明这个部门有员工。

SQL语句会是这样:

SELECT 部门名称
FROM 部门表 d
WHERE EXISTS (
    SELECT 1 FROM 员工表 e  -- 这里SELECT 1是习惯写法,意思是我只关心有没有记录,不关心内容
    WHERE e.部门ID = d.部门ID  -- 这个条件把主查询和子查询关联起来了
);

这个子查询用在了 WHERE EXISTS 后面,它的执行方式是:主查询从部门表取出一条记录(销售部”),然后把它的部门ID(比如10)交给子查询,子查询就去员工表里找,看有没有部门ID=10的员工,只要找到至少一个,EXISTS就返回“真”,销售部”这条记录就会被主查询选中,接着主查询再取下一条部门记录,重复这个过程。

常见的子查询类型和小结

根据子查询返回的结果,我们可以把它分为几种:

  • 标量子查询:像例子1那样,子查询只返回一个单一的值(一个数字、一个字符串),可以直接用 =, >, < 这些比较符来比较。
  • 列子查询:子查询返回一列数据(多个值),这时主查询常用 IN, NOT IN, ANY, ALL 这些操作符。SELECT 姓名 FROM 员工表 WHERE 部门ID IN (SELECT 部门ID FROM 部门表 WHERE 地点='北京'),就是找出办公地点在北京的所有部门的员工。
  • 表子查询:像例子2那样,子查询返回一个完整的结果集(多行多列),可以当作一张临时表来使用。
  • 关联子查询:像例子3那样,子查询的执行依赖于主查询传入的值(e.部门ID = d.部门ID),它会为外部查询的每一行都执行一次。

子查询是一个非常强大的工具,它通过将复杂问题分解成多个简单的步骤,让我们能够用SQL处理更灵活、更复杂的业务逻辑,核心要点就是:先想清楚步骤,让里面的“助手查询”(子查询)先执行,然后把结果交给外面的“主查询”去用,多结合实际的例子练习,就能很快掌握它。 综合参考了常见的SQL教程和数据库知识分享,如菜鸟教程、CSDN博客等技术社区中关于子查询的通俗化讲解和实例演示)

数据库子查询怎么用?实例讲解和常见例子分享,帮你快速理解子查询操作