【MySQL】表的连接和复合查询

欢迎来到Cefler的博客😁

🕌博客主页:折纸花满衣

🏠个人专栏:MySQL


目录

👉🏻连接JOIN

在MySQL中,连接(JOIN)是用于从两个或多个表中检索相关行的强大工具。通过使用JOIN,你可以基于这些表之间的某些相关列之间的关系来组合这些表的行。以下是关于JOIN的详细解释和示例:

🌍 1. INNER JOIN(内连接)

INNER JOIN返回两个表中满足连接条件的所有行。只有在两个表中都存在匹配的行时,这些行才会出现在结果集中。

示例

假设我们有两个表:customersorders。我们想找出所有下过订单的客户及其订单详情。

sql 复制代码
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值。

示例

假设我们想要列出所有客户,无论他们是否下过订单。

sql 复制代码
SELECT customers.customer_name, orders.order_id, orders.order_date
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id;

在这个示例中,结果集将包含customers表中的所有客户。对于下过订单的客户,order_idorder_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):

sql 复制代码
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返回左表中的每一行与右表中的每一行的组合,也称为笛卡尔积。这通常不是一个常用的连接类型,但在某些情况下可能很有用。

示例

sql 复制代码
SELECT * FROM customers
CROSS JOIN orders;

🌍 注意事项:

  • 在使用JOIN时,确保连接条件正确,以避免返回错误或意外的结果。
  • 当连接多个表时,为了简化查询和提高可读性,可以为表指定别名。
  • 在涉及大量数据的查询中,注意性能优化。使用索引、调整查询逻辑和避免不必要的JOIN操作可以帮助提高性能。
  • 使用EXPLAIN命令来分析查询的执行计划,以便进行性能调优。

👉🏻子查询

🌍1. 子查询在SELECT子句中使用

子查询可以在SELECT子句中使用,以从其他表中检索值,并将其用作外部查询的一部分。

示例 :假设我们有两个表:customers(包含客户信息)和orders(包含订单信息)。我们想要列出每个客户的订单总数。

sql 复制代码
SELECT customer_name, 
       (SELECT COUNT(*) FROM orders WHERE orders.customer_id = customers.customer_id) AS order_count
FROM customers;

在这个示例中,子查询对于每个customers表中的客户都会执行一次,以计算其订单数量。

🌍2. 子查询在FROM子句中使用(内联视图或派生表)

示例:查找每个客户的订单总数。

sql 复制代码
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子句中使用

示例:查找价格高于平均价格的产品。

sql 复制代码
SELECT product_name, price
FROM products
WHERE price > (
    SELECT AVG(price)
    FROM products
);

在这个示例中,内部子查询计算产品的平均价格。然后,外部查询选择价格高于平均价格的产品。

注意事项:

  • 子查询可以返回单个值、一行值、一列值或一个表的结果集。
  • 子查询的性能可能因数据量和查询的复杂性而异。优化器会尝试有效地执行子查询,但有时可能需要手动调整查询以提高性能。
  • 使用子查询时,确保连接条件和外层查询的WHERE条件逻辑清晰,以避免不必要的计算或错误的结果。
  • 在某些情况下,可以使用JOIN代替子查询,以提高查询的性能和可读性。但是,子查询在某些场景中(如聚合函数和条件语句中)仍然非常有用。

👉🏻合并查询

UNIONUNION ALL 是 SQL 中用于合并两个或多个 SELECT 语句结果集的操作符。这两个操作符的主要区别在于它们如何处理重复的行。

🌍 UNION

UNION 操作符用于合并两个或多个 SELECT 语句的结果集,但不包括重复的行。也就是说,它会从所有 SELECT 语句的结果集中删除重复的行,然后返回唯一的行。

语法

sql 复制代码
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

注意

  1. 所有的 SELECT 语句必须具有相同的列数。
  2. 这些列也必须具有相似的数据类型。
  3. 列的顺序必须相同。

示例

假设有两个表 employees1employees2,它们都有 nameage 列。如果我们想要获取两个表中所有不重复的员工名称,可以使用 UNION

sql 复制代码
SELECT name FROM employees1
UNION
SELECT name FROM employees2;

🌍 UNION ALL

UNION ALL 操作符与 UNION 类似,但它会返回所有行,包括重复的行。也就是说,它不会删除任何重复的行。

语法

sql 复制代码
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

示例

使用与上面相同的 employees1employees2 表,如果我们想要获取两个表中所有的员工名称(包括重复的名称),可以使用 UNION ALL

sql 复制代码
SELECT name FROM employees1
UNION ALL
SELECT name FROM employees2;

🌍 性能考虑

由于 UNION 需要删除重复的行,所以它的性能通常比 UNION ALL 差。如果你知道结果集中不会有重复的行,或者你想要包括重复的行,那么使用 UNION ALL 会更加高效。

🌍 其他注意事项

  • 在使用 UNIONUNION ALL 时,你可以对每个 SELECT 语句使用 ORDER BY 子句,但只能有一个 ORDER BY 子句,并且它必须位于最后一个 SELECT 语句之后。如果你想要对整个结果集进行排序,而不是对每个 SELECT 语句的结果集进行排序,那么你应该这样做。
  • 如果你想要对每个 SELECT 语句的结果集进行排序,并在合并后保留这些排序,那么你需要使用其他方法,如子查询或临时表。

如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长


相关推荐
Majoy28 分钟前
HBase
大数据·数据库·hbase
夜光小兔纸1 小时前
oracle查询出表中某几个字段值不唯一的数据
数据库·sql·oracle
deadknight93 小时前
Oracle密码过期处理方式
数据库·oracle
Ljubim.te3 小时前
数据库第01讲章节测验(选项顺序可能不同)
数据库
吱吱喔喔3 小时前
数据分表和分库原理
数据库·分表·分库
快乐非自愿3 小时前
KES数据库实践指南:探索KES数据库的事务隔离级别
数据库·oracle
一只fish3 小时前
Oracle的RECYCLEBIN回收站:轻松恢复误删对象
数据库·oracle
weixin_440401693 小时前
分布式锁——基于Redis分布式锁
java·数据库·spring boot·redis·分布式
TOR-NADO3 小时前
数据库概念题总结
数据库·oracle
云计算练习生3 小时前
理解MySQL核心技术:存储过程与函数的强大功能
数据库·mysql·存储过程·函数·mysql函数