MySQL 高级查询:JOIN、子查询、窗口函数
目录
- 一、JOIN:连接查询
- 1.1 INNER JOIN:内连接
- 1.2 LEFT JOIN:左连接
- 1.3 RIGHT JOIN:右连接
- 1.4 FULL JOIN:全连接
- 二、子查询:嵌套查询
- 2.1 WHERE 子句中的子查询
- 2.2 FROM 子句中的子查询
- 2.3 SELECT 子句中的子查询
- 三、窗口函数:Window Function
- 3.1 ROW_NUMBER()
- 3.2 RANK() 和 DENSE_RANK()
- 3.3 NTILE()
- 3.4 LAG() 和 LEAD()
- 四、总结
在数据处理和分析中,MySQL 的高级查询功能是不可或缺的利器。通过掌握 JOIN、子查询以及窗口函数(Window Function)的使用,能够让你以更高效的方式构建复杂且功能强大的 SQL 查询。本文将详细探讨这三类高级查询技术,结合简单易懂的代码示例,帮助你快速理解并应用到实际工作中。
一、JOIN:连接查询
JOIN 用于将两个或多个表的数据基于某些条件组合在一起。MySQL 支持多种 JOIN 类型,如 INNER JOIN
、LEFT JOIN
、RIGHT JOIN
和 FULL JOIN
。这些 JOIN 在不同场景下各有用途。
1.1 INNER JOIN:内连接
内连接是最常见的 JOIN 类型,它返回两个表中匹配的记录。
SELECT orders.order_id, customers.customer_name
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
1.2 LEFT JOIN:左连接
左连接返回左边表的所有记录,即使右边表中没有匹配的记录。
SELECT orders.order_id, customers.customer_name
FROM orders
LEFT JOIN customers ON orders.customer_id = customers.customer_id;
1.3 RIGHT JOIN:右连接
右连接返回右边表的所有记录,即使左边表中没有匹配的记录。
SELECT orders.order_id, customers.customer_name
FROM orders
RIGHT JOIN customers ON orders.customer_id = customers.customer_id;
1.4 FULL JOIN:全连接
全连接返回两个表的所有记录,无论是否匹配。MySQL 不直接支持 FULL JOIN,但可以通过 UNION 模拟。
SELECT orders.order_id, customers.customer_name
FROM orders
LEFT JOIN customers ON orders.customer_id = customers.customer_id
UNION
SELECT orders.order_id, customers.customer_name
FROM orders
RIGHT JOIN customers ON orders.customer_id = customers.customer_id;
二、子查询:嵌套查询
子查询是指在 SQL 查询中嵌套的查询语句。子查询可以用于 WHERE、FROM 或 SELECT 子句中。
2.1 WHERE 子句中的子查询
在 WHERE 子句中使用子查询,可以基于子查询的结果筛选记录。
SELECT customer_name
FROM customers
WHERE customer_id IN (SELECT customer_idFROM ordersWHERE order_date > '2024-01-01'
);
2.2 FROM 子句中的子查询
在 FROM 子句中使用子查询,可以将子查询的结果作为临时表使用。
SELECT customer_name, total_orders
FROM (SELECT customer_id, COUNT(*) AS total_ordersFROM ordersGROUP BY customer_id
) AS subquery
INNER JOIN customers ON subquery.customer_id = customers.customer_id;
2.3 SELECT 子句中的子查询
在 SELECT 子句中使用子查询,可以为每个行添加子查询的结果。
SELECT customer_name, (SELECT COUNT(*)FROM ordersWHERE orders.customer_id = customers.customer_id
) AS total_orders
FROM customers;
三、窗口函数:Window Function
窗口函数在 MySQL 8.0 中引入,它允许在查询结果中对一组行执行计算,同时保留每一行的信息。
3.1 ROW_NUMBER()
ROW_NUMBER()
为每一行分配一个唯一的序号。
SELECT customer_name, order_date,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS row_num
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
3.2 RANK() 和 DENSE_RANK()
RANK()
和 DENSE_RANK()
用于对结果集中的行进行排名。
SELECT customer_name, order_total,
RANK() OVER (PARTITION BY customer_id ORDER BY order_total DESC) AS rank,
DENSE_RANK() OVER (PARTITION BY customer_id ORDER BY order_total DESC) AS dense_rank
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
3.3 NTILE()
NTILE()
将结果集分成指定数量的组。
SELECT customer_name, order_total,
NTILE(4) OVER (ORDER BY order_total DESC) AS quartile
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
3.4 LAG() 和 LEAD()
LAG()
和 LEAD()
用于访问窗口中前后行的值。
SELECT customer_name, order_total,
LAG(order_total) OVER (ORDER BY order_date) AS previous_order_total,
LEAD(order_total) OVER (ORDER BY order_date) AS next_order_total
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
四、总结
通过本文的介绍,你已经了解了 MySQL 中的 JOIN、子查询和窗口函数这三类高级查询技术。JOIN 用于组合不同表的数据;子查询可以在 WHERE、FROM 或 SELECT 子句中提供更复杂的筛选和计算;窗口函数则极大地增强了 SQL 的数据分析能力。熟练掌握这些技术,将使你在数据处理和分析工作中更加得心应手。希望本文的示例和讲解能帮助你更好地应用这些高级查询功能。