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

相关推荐
曾凡宇先生2 小时前
mysql连接问题
数据库
Dream of maid2 小时前
Python(11) 进程与线程
开发语言·python
jwt7939279372 小时前
MySQL 批量删除海量数据的几种方法
数据库·mysql
杰克尼2 小时前
springCloud_day08(Elasticsearch)
java·spring·spring cloud
Yvonne爱编码2 小时前
数据库---Day8 多表联合查询
数据库
cici158742 小时前
非线性模型预测控制(NMPC)基于CasADi的MATLAB实现
开发语言·matlab
Renhao-Wan2 小时前
Java 中 Integer 对象的缓存机制与包装类特性
java·缓存
CHANG_THE_WORLD2 小时前
PDFIUM如何处理宽度数组
java·linux·服务器
云飞云共享云桌面2 小时前
SolidWorks三维设计不用单独买电脑,1台服务器10个设计用
运维·服务器·数据库·3d·电脑