管理

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

Posted on 2026-04-02 10:22  lzhdim  阅读(18)  评论(0)    收藏  举报

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

学习内容

  1. 子查询
    • 用 () 包装独立查询,结果作为外部查询条件。
    • 可用于比较(如 >)或集合匹配(如 IN)。
    • 子查询返回单值时用比较运算符,多值时用 IN。
  2. IN 运算符
    • 检查值是否在子查询结果集中,NOT IN 检查不在其中。
    • 常用于筛选未关联的记录。
  3. 子查询与连接对比
    • 子查询直接表达筛选逻辑,可读性高。
    • 内连接(JOIN)仅返回匹配记录,左连接(LEFT JOIN)结合 IS NULL 可替代 NOT IN。
    • 选择依据代码可读性与性能。
  4. 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 数据库。后续将探讨更多查询优化技巧。

 

Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved