子查询(Subquery)是嵌套在另一个SQL查询中的查询,也称为内部查询或嵌套查询。子查询可以出现在SELECT、FROM、WHERE、HAVING等子句中,为主查询提供数据。
返回单行单列结果的子查询,通常与比较运算符(=, >, <, >=, <=, <>)一起使用。
SELECT employee_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
返回多行结果的子查询,通常与IN、ANY、ALL等运算符一起使用。
SELECT product_name, price
FROM products
WHERE product_id IN (SELECT product_id FROM order_items WHERE quantity > 10);
返回多列结果的子查询。
SELECT employee_id, first_name, last_name
FROM employees
WHERE (department_id, salary) IN
(SELECT department_id, MAX(salary) FROM employees GROUP BY department_id);
子查询引用外部查询的列,为外部查询的每一行执行一次。
SELECT e.employee_id, e.last_name, e.salary
FROM employees e
WHERE e.salary > (SELECT AVG(salary) FROM employees WHERE department_id = e.department_id);
最常见的子查询位置,用于过滤数据。
SELECT customer_name
FROM customers
WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date > '2023-01-01');
子查询结果作为临时表使用。
SELECT d.department_name, e.avg_salary
FROM departments d
JOIN (SELECT department_id, AVG(salary) as avg_salary FROM employees GROUP BY department_id) e
ON d.department_id = e.department_id;
必须返回单行单列结果。
SELECT product_name,
price,
(SELECT AVG(price) FROM products) as avg_price,
price - (SELECT AVG(price) FROM products) as price_diff
FROM products;
对分组结果进行过滤。
SELECT department_id, COUNT(*) as emp_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > (SELECT AVG(emp_count)
FROM (SELECT COUNT(*) as emp_count FROM employees GROUP BY department_id));
检查值是否在子查询结果集中。
SELECT product_name
FROM products
WHERE product_id IN (SELECT product_id FROM order_items WHERE quantity > 5);
检查子查询是否返回任何行(更关注存在性而非具体值)。
SELECT customer_name
FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);
与比较运算符一起使用,表示与子查询结果中的任意值比较。
SELECT employee_name, salary
FROM employees
WHERE salary > ANY (SELECT salary FROM employees WHERE department_id = 10);
与比较运算符一起使用,表示与子查询结果中的所有值比较。
SELECT product_name, price
FROM products
WHERE price > ALL (SELECT price FROM products WHERE category = 'Electronics');
SELECT customer_id, customer_name
FROM customers
WHERE customer_id NOT IN (SELECT DISTINCT customer_id FROM orders);
SELECT e.employee_id, e.last_name, e.department_id, e.salary
FROM employees e
WHERE e.salary = (SELECT MAX(salary)
FROM employees
WHERE department_id = e.department_id);
SELECT p.product_id, p.product_name, SUM(oi.quantity * oi.unit_price) as total_sales
FROM products p
JOIN order_items oi ON p.product_id = oi.product_id
GROUP BY p.product_id, p.product_name
HAVING SUM(oi.quantity * oi.unit_price) >
(SELECT AVG(total_sales)
FROM (SELECT SUM(quantity * unit_price) as total_sales
FROM order_items
GROUP BY product_id));
掌握子查询是SQL高级应用的关键,合理使用可以解决复杂的数据查询问题,但也要注意性能影响。