SQL 入门 9:SQL 高级子查询:ANY、EXISTS 与多位置应用

以下为 SQL 中高级子查询的用法解析,涵盖 ANY、EXISTS 及子查询的多位置应用。

学习内容

  1. ANY 关键字
  • 与子查询结果集的任一值比较,等效于 IN(用于相等时)。
  • 返回多值时使用。
  • 相关子查询

    • 子查询依赖外部查询的列,逐行执行。
    • 示例:比较员工薪资与其部门平均值。
  • EXISTS

    • EXISTS:逐行检查,子查询结果集大时性能较优。
    • IN:先执行子查询,外部表大时更快。
    • 连接:需根据需求选择(如 LEFT JOIN 加 IS NULL)。
    • 判断子查询是否有记录返回,适用于相关子查询。
    • 与 IN 和连接对比:
  • SELECT 中的子查询

    • 在列中嵌入子查询,计算动态值。
    • 限制:同一级别查询不能直接引用新列名,需通过外层查询或后续语句(如 ORDER BY、HAVING)使用。
  • FROM 中的子查询

    • 将子查询结果作为虚拟表,需指定别名。
    • 可用于复杂数据处理,类似临时表。

    示例代码与讲解

    1. ANY 关键字

    SELECT *

    FROM clients

    WHERE client_id IN (

    SELECT client_id

    FROM invoices

    GROUP BY client_id

    HAVING COUNT(*) > 2

    );

    • 找出发票数 > 2 的客户。

    SELECT *

    FROM clients

    WHERE client_id = ANY (

    SELECT client_id

    FROM invoices

    GROUP BY client_id

    HAVING COUNT(*) > 2

    );

    • 用 ANY 替代 IN,效果相同,表示匹配子查询任一值。

    2. 相关子查询

    USE sql_hr;

    SELECT *

    FROM employees e

    WHERE salary > (

    SELECT AVG(salary)

    FROM employees e2

    WHERE e2.office_id = e.office_id

    );

    • 找出薪资高于所在办公室平均值的员工,子查询与外部 office_id 相关。

    3. EXISTS

    USE sql_invoicing;

    SELECT client_id, name

    FROM clients c

    WHERE EXISTS (

    SELECT client_id

    FROM invoices ci

    WHERE c.client_id = ci.client_id

    );

    • 找出有发票的客户,逐行检查是否存在匹配记录。

    4. SELECT 中的子查询

    SELECT invoice_id, invoice_total,

    (SELECT AVG(invoice_total) FROM invoices) AS avginvoice_total,

    (SELECT avginvoice_total) - invoice_total AS difference

    FROM invoices;

    • 计算每张发票与平均值的差额。
    • 注意:avginvoice_total 不能直接在同级使用,需通过外层查询引用。

    5. FROM 中的子查询

    SELECT *

    FROM (

    SELECT c.client_id, name,

    (SELECT SUM(i.invoice_total) FROM invoices i WHERE c.client_id = i.client_id) AS total_sales,

    (SELECT AVG(invoice_total) FROM invoices) AS AVERAGE,

    (SELECT total_sales - AVERAGE) AS difference

    FROM clients c

    ) AS SUMMARY

    WHERE total_sales IS NOT NULL;

    • 将子查询结果作为虚拟表 SUMMARY,筛选非空销售总额。

    作业

    1. 相关子查询

    USE sql_invoicing;

    SELECT *

    FROM invoices i

    WHERE invoice_total > (

    SELECT AVG(invoice_total)

    FROM invoices i2

    WHERE i.client_id = i2.client_id

    );

    • 找出总额高于其客户平均值的发票。

    2. EXISTS

    USE sql_store;

    SELECT *

    FROM products p

    WHERE NOT EXISTS (

    SELECT *

    FROM order_items

    WHERE p.product_id = order_items.product_id

    );

    • 找出从未被订购的产品。

    3. SELECT 中的子查询

    USE sql_invoicing;

    CLEARSELECT c.client_id, name,

    (SELECT SUM(i.invoice_total) FROM invoices i WHERE c.client_id = i.client_id) AS total_sales,

    (SELECT AVG(invoice_total) FROM invoices) AS AVERAGE,

    (SELECT total_sales - AVERAGE) AS difference

    FROM clients c;

    • 计算每个客户的销售总额、平均值及差额,避免 GROUP BY。

    总结

    本次解析了 ANY(等效 IN)、相关子查询、EXISTS 及子查询在 SELECT 和 FROM 中的应用。基于 sql_invoicing、sql_hr 和 sql_store 数据库。后续将探讨视图与事务。

相关推荐
昵称画9 小时前
交接班记录电子化:三班之间的信息不漏
开发语言·数据库·人工智能·低代码·php
“AI国潮设计-小江”10 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
传奇开心果编程10 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
code tsunami10 小时前
【无标题】
开发语言·python
缓慢更新10 小时前
审批的加签与会签:多人意见怎么合
android·java·数据库·低代码·rxjava
CodeGL10 小时前
10、Python基础之进程和线程
开发语言·python
跨境联盟11 小时前
大健康实体如何搭建产品差异化:对比普通营养品与合规跨境膳食补充剂服务模式
数据库·ai·健康医疗·健康管理·精准营养
有想法的py工程师11 小时前
PostgreSQL EXPLAIN中的Cost模型分析(random_page_cost参数):优化器眼中的代价世界与执行计划生成
数据库·postgresql
前进的李工11 小时前
飞书企业知识库设计+后端高频八股
数据库·redis·后端·mysql·性能优化·飞书·rag
yuniko-n11 小时前
【JUC】volatile 非原子性深入解析
java