SQL 入门 8:SQL 复杂查询:子查询与ALL关键词

以下为 SQL 中复杂查询的用法解析,聚焦子查询与连接。

学习内容

  1. 子查询
  • 用 () 包装独立查询,结果作为外部查询条件。
  • 可用于比较(如 >)或集合匹配(如 IN)。
  • 子查询返回单值时用比较运算符,多值时用 IN。
  • IN 运算符

    • 检查值是否在子查询结果集中,NOT IN 检查不在其中。
    • 常用于筛选未关联的记录。
  • 子查询与连接对比

    • 子查询直接表达筛选逻辑,可读性高。
    • 内连接(JOIN)仅返回匹配记录,左连接(LEFT JOIN)结合 IS NULL 可替代 NOT IN。
    • 选择依据代码可读性与性能。
  • ALL 关键字

    • 比较值与子查询结果集的所有值,如 > ALL 表示大于所有值。
    • 可替代单值比较(如 MAX)。

    示例代码与讲解

    1. 子查询

    SELECT *

    FROM products

    WHERE unit_price > (

    SELECT unit_price

    FROM products

    WHERE product_id = 3

    );

    • 找出 products 中比 ID 为 3 产品更贵的产品。

    2. IN 运算符

    SELECT *

    FROM products

    WHERE product_id NOT IN (

    SELECT DISTINCT product_id

    FROM order_items

    );

    • 找出未被订购的产品,DISTINCT 避免重复。

    3. 子查询与连接对比

    USE sql_invoicing;

    SELECT *

    FROM clients

    WHERE client_id NOT IN (

    SELECT DISTINCT client_id

    FROM invoices

    );

    • 子查询找出无发票的客户。

    SELECT *

    FROM clients

    JOIN invoices USING (client_id);

    • 内连接仅返回有发票的客户。

    SELECT *

    FROM clients

    LEFT JOIN invoices USING (client_id)

    WHERE invoice_id IS NULL;

    • 左连接找出无发票的客户(invoice_id 为空),结果同子查询,但子查询更直观。

    4. ALL 关键字

    SELECT *

    FROM invoices

    WHERE invoice_total > (

    SELECT MAX(invoice_total)

    FROM invoices

    WHERE client_id = 3

    );

    • 找出大于客户 3 最大发票总额的发票。

    SELECT *

    FROM invoices

    WHERE invoice_total > ALL (

    SELECT invoice_total

    FROM invoices

    WHERE client_id = 3

    );

    • 用 ALL 替代 MAX,效果相同。

    作业

    1. 子查询 - 高薪员工

    USE sql_hr;

    SELECT first_name, last_name, salary

    FROM employees

    WHERE salary > (

    SELECT AVG(salary) AS AVG_salary

    FROM employees

    );

    • 找出薪资高于平均值的员工。

    2. IN - 无发票客户

    USE sql_invoicing;

    SELECT *

    FROM clients

    WHERE client_id NOT IN (

    SELECT DISTINCT client_id

    FROM invoices

    );

    • 找出无发票的客户。

    3. 子查询与连接 - 订购产品 3 的客户

    USE sql_store;

    SELECT customer_id, first_name, last_name

    FROM customers

    WHERE customer_id IN (

    SELECT customer_id

    FROM order_items

    JOIN orders USING (order_id)

    WHERE product_id = 3

    );

    • 方法 1:子查询找出订购产品 3 的客户。

    SELECT DISTINCT customer_id, first_name, last_name

    FROM customers c

    JOIN orders USING (customer_id)

    JOIN order_items oi USING (order_id)

    WHERE oi.product_id = 3;

    • 方法 2:连接实现,DISTINCT 避免重复。

    总结

    本次解析了子查询(比较与 IN)、子查询与连接的对比及 ALL 关键字用法。基于 sql_store、sql_hr 和 sql_invoicing 数据库。后续将探讨更多查询优化技巧。

相关推荐
Gauss松鼠会2 分钟前
GaussDB 中 gsql 与 DBeaver(JDBC)客户端工具查询时间不一致:原因、排查与处理
运维·服务器·数据库·sql·gaussdb·经验总结
Elastic 中国社区官方博客8 分钟前
基于 Jina OCR v1 与 Elasticsearch 的 PDF 智能混合检索与 RAG 系统实战指南
大数据·数据库·elasticsearch·搜索引擎·ocr·jina
渣渣盟10 分钟前
Flink SQL 流批一体:从 SQL 到执行计划,优化器如何工作?
大数据·sql·flink
我不会起名字32214 分钟前
MySQL 8.0 迁移后 SQL 变慢:执行计划里 3 类被忽略的成本差异
mysql·explain·执行计划·索引下推·成本模型
楚识科技15 分钟前
信创环境下 OCR 部署实践:从麒麟系统到达梦数据库的全栈适配
数据库·ocr
飞浪纪元[FWC–FE]20 分钟前
Qt 构建排错实录:从 MSB 1009 到生成器选型
开发语言·数据库·qt
Paper数据分析-经管学术20 分钟前
1985-2026年中国低空经济专利明细数据库
数据库
RuoyiOffice20 分钟前
SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
java·数据库·spring boot·opengauss·信创
画中有画32 分钟前
时序数据库在物联网系统中的应用
数据库·物联网·时序数据库
Decay__7 小时前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构