欢迎来到Cefler的博客😁
🕌博客主页:折纸花满衣
🏠个人专栏:MySQL
目录
- 👉🏻连接JOIN
- 👉🏻子查询
- 👉🏻合并查询
👉🏻连接JOIN
在MySQL中,连接(JOIN)是用于从两个或多个表中检索相关行的强大工具。通过使用JOIN,你可以基于这些表之间的某些相关列之间的关系来组合这些表的行。以下是关于JOIN的详细解释和示例:
🌍 1. INNER JOIN(内连接)
INNER JOIN返回两个表中满足连接条件的所有行。只有在两个表中都存在匹配的行时,这些行才会出现在结果集中。
示例:
假设我们有两个表:customers
和 orders
。我们想找出所有下过订单的客户及其订单详情。
SELECT customers.customer_name, orders.order_id, orders.order_date
FROM customers
INNER JOIN orders ON customers.customer_id = orders.customer_id;
在这个示例中,我们基于customer_id
列将customers
表和orders
表连接在一起。结果集将包含所有下过订单的客户及其对应的订单ID和订单日期。
🌍 2. LEFT JOIN(左连接)
LEFT JOIN从左表中选择所有的行,以及右表中满足连接条件的行。如果右表中没有匹配的行,则结果中右表的部分将包含NULL值。
示例:
假设我们想要列出所有客户,无论他们是否下过订单。
SELECT customers.customer_name, orders.order_id, orders.order_date
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id;
在这个示例中,结果集将包含customers
表中的所有客户。对于下过订单的客户,order_id
和order_date
列将包含相应的值;对于没有下过订单的客户,这些列将包含NULL值。
🌍 3. RIGHT JOIN(右连接)
RIGHT JOIN与LEFT JOIN相反,它从右表中选择所有的行,以及左表中满足连接条件的行。如果左表中没有匹配的行,则结果中左表的部分将包含NULL值。
注意:在实际应用中,RIGHT JOIN的使用相对较少,因为你可以通过调整表的顺序和使用LEFT JOIN来达到相同的效果。
🌍4. FULL JOIN(全连接)
FULL JOIN返回左表和右表中满足连接条件的所有行。如果某一边没有匹配的行,则结果中对应的一边将包含NULL值。但是,MySQL本身不支持FULL JOIN。不过,你可以通过组合LEFT JOIN和UNION来达到相同的效果。
示例(模拟FULL JOIN):
SELECT * FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
UNION
SELECT * FROM customers
RIGHT JOIN orders ON customers.customer_id = orders.customer_id
WHERE customers.customer_id IS NULL;
🌍 5. 交叉连接(CROSS JOIN)
CROSS JOIN返回左表中的每一行与右表中的每一行的组合,也称为笛卡尔积。这通常不是一个常用的连接类型,但在某些情况下可能很有用。
示例:
SELECT * FROM customers
CROSS JOIN orders;
🌍 注意事项:
- 在使用JOIN时,确保连接条件正确,以避免返回错误或意外的结果。
- 当连接多个表时,为了简化查询和提高可读性,可以为表指定别名。
- 在涉及大量数据的查询中,注意性能优化。使用索引、调整查询逻辑和避免不必要的JOIN操作可以帮助提高性能。
- 使用
EXPLAIN
命令来分析查询的执行计划,以便进行性能调优。
👉🏻子查询
🌍1. 子查询在SELECT子句中使用
子查询可以在SELECT子句中使用,以从其他表中检索值,并将其用作外部查询的一部分。
示例:假设我们有两个表:customers
(包含客户信息)和orders
(包含订单信息)。我们想要列出每个客户的订单总数。
SELECT customer_name,
(SELECT COUNT(*) FROM orders WHERE orders.customer_id = customers.customer_id) AS order_count
FROM customers;
在这个示例中,子查询对于每个customers
表中的客户都会执行一次,以计算其订单数量。
🌍2. 子查询在FROM子句中使用(内联视图或派生表)
示例:查找每个客户的订单总数。
SELECT c.customer_name, co.order_count
FROM customers c
JOIN (
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
) AS co ON c.customer_id = co.customer_id;
在这个示例中,内部子查询(派生表)首先计算每个客户的订单数,并将其作为临时结果集co
。然后,外部查询将customers
表与这个临时结果集连接,以检索每个客户的名称和订单总数。
🌍 3. 子查询在WHERE子句中使用
示例:查找价格高于平均价格的产品。
SELECT product_name, price
FROM products
WHERE price > (
SELECT AVG(price)
FROM products
);
在这个示例中,内部子查询计算产品的平均价格。然后,外部查询选择价格高于平均价格的产品。
注意事项:
- 子查询可以返回单个值、一行值、一列值或一个表的结果集。
- 子查询的性能可能因数据量和查询的复杂性而异。优化器会尝试有效地执行子查询,但有时可能需要手动调整查询以提高性能。
- 使用子查询时,确保连接条件和外层查询的WHERE条件逻辑清晰,以避免不必要的计算或错误的结果。
- 在某些情况下,可以使用JOIN代替子查询,以提高查询的性能和可读性。但是,子查询在某些场景中(如聚合函数和条件语句中)仍然非常有用。
👉🏻合并查询
UNION
和 UNION ALL
是 SQL 中用于合并两个或多个 SELECT
语句结果集的操作符。这两个操作符的主要区别在于它们如何处理重复的行。
🌍 UNION
UNION
操作符用于合并两个或多个 SELECT
语句的结果集,但不包括重复的行。也就是说,它会从所有 SELECT
语句的结果集中删除重复的行,然后返回唯一的行。
语法:
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注意:
- 所有的
SELECT
语句必须具有相同的列数。 - 这些列也必须具有相似的数据类型。
- 列的顺序必须相同。
示例:
假设有两个表 employees1
和 employees2
,它们都有 name
和 age
列。如果我们想要获取两个表中所有不重复的员工名称,可以使用 UNION
:
SELECT name FROM employees1
UNION
SELECT name FROM employees2;
🌍 UNION ALL
UNION ALL
操作符与 UNION
类似,但它会返回所有行,包括重复的行。也就是说,它不会删除任何重复的行。
语法:
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
示例:
使用与上面相同的 employees1
和 employees2
表,如果我们想要获取两个表中所有的员工名称(包括重复的名称),可以使用 UNION ALL
:
SELECT name FROM employees1
UNION ALL
SELECT name FROM employees2;
🌍 性能考虑
由于 UNION
需要删除重复的行,所以它的性能通常比 UNION ALL
差。如果你知道结果集中不会有重复的行,或者你想要包括重复的行,那么使用 UNION ALL
会更加高效。
🌍 其他注意事项
- 在使用
UNION
或UNION ALL
时,你可以对每个SELECT
语句使用ORDER BY
子句,但只能有一个ORDER BY
子句,并且它必须位于最后一个SELECT
语句之后。如果你想要对整个结果集进行排序,而不是对每个SELECT
语句的结果集进行排序,那么你应该这样做。 - 如果你想要对每个
SELECT
语句的结果集进行排序,并在合并后保留这些排序,那么你需要使用其他方法,如子查询或临时表。
如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长