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 数据库。后续将探讨视图与事务。

相关推荐
信誓旦旦的程序猿1 分钟前
【零依赖量化数据实战 #25】北交所技术指标与基本面
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
祢真伟大2 分钟前
Oracle含LOB大字段表的存储占用统计
数据库·oracle
2601_966949653 分钟前
Python 量化开发为什么适合使用金融数据 SDK?从数据获取到策略研究的工程化实践
开发语言·python·数据分析·量化交易·股票数据·quantdash
万年咸鱼5 分钟前
Java ArrayList 详解:原理、用法与实战
java·开发语言·windows
长友cy9 分钟前
Qt官方示例Application源码阅读
开发语言·qt
程序员良辰16 分钟前
服务器 JDK 环境变量配置:一键安装和手动配置有什么区别?
开发语言·python
Inhand-Victor19 分钟前
从 CAN 总线到 AWS IoT:EC312 边缘计算网关实现 CAN 数据云端接入
数据库
奈斯先生Vector23 分钟前
本地图片识别怎么接入多模态 AI?用 Python API 理解 GPT-4o Vision 的真实工作流
开发语言·人工智能·windows·python·网络协议·http·aigc
OPEN-F27 分钟前
C++17新特性精讲:结构化绑定、if constexpr与实用类型
开发语言·c++
CoderYanger28 分钟前
A.每日一题:3345. 最小可整除数位乘积 I
java·数据结构·程序人生·算法·leetcode·面试·学习方法