图解SQL的各种连接(Inner join,outer join,left join,right join)

本文通过实例演示了SQL中七种不同的Join类型:Inner Join、Full Outer Join、Left Outer Join、Right Outer Join及其特定条件下的应用,帮助读者理解每种Join操作的作用及应用场景。

原文地址(原文写的挺全的,直接拿过来了)

由于 SQL Join 似乎被默认为基础,同时利用 ‘文氏图表’ 解释它,乍一看似乎是很自然的选择。然而,就像文章下面说的,我也发现在实际测试中,文氏图并没有完全符合SQL Join 语法。


     通过图文并茂的方式对SQL的Join进行简单的介绍:join大致分为以下七种情况:


1准备数据

  1. DROP TABLE [dbo].[test_a]  
  2. GO  
  3. CREATE TABLE [dbo].[test_a] (  
  4. [id] int NULL ,  
  5. [name] varchar(255) NULL   
  6. )  
  7. GO  
  8. -- ----------------------------  
  9. -- Records of test_a  
  10. -- ----------------------------  
  11. INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'1', N'苹果')  
  12. GO  
  13. GO  
  14. INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'2', N'橘子')  
  15. GO  
  16. GO  
  17. INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'3', N'菠萝')  
  18. GO  
  19. GO  
  20. INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'4', N'香蕉')  
  21. GO  
  22. GO  
  23. INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'5', N'西瓜')  
  24. GO  
  25. GO  
  26. -----------------------------------------------------------  
  27. DROP TABLE [dbo].[test_b]  
  28. GO  
  29. CREATE TABLE [dbo].[test_b] (  
  30. [id] int NULL ,  
  31. [name] varchar(255) NULL   
  32. )  
  33. GO  
  34.   
  35. -- ----------------------------  
  36. -- Records of test_b  
  37. -- ----------------------------  
  38. INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'1', N'梨子')  
  39. GO  
  40. GO  
  41. INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'2', N'苹果')  
  42. GO  
  43. GO  
  44. INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'3', N'草莓')  
  45. GO  
  46. GO  
  47. INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'4', N'桃子')  
  48. GO  
  49. GO  
  50. INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'5', N'香蕉')  
  51. GO  
  52. GO   

2示例介绍

A.Inner join

产生A和B的交集。

  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. INNER JOIN test_b ON test_a.name = test_b.name   
222

B. Full outer join

产生A和B的并集。对于没有匹配的记录,则以null做为值。
  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. FULL OUTER JOIN test_b ON test_a.name = test_b.name   
222

C.Left outer join 

产生表A的完全集,而B表中匹配的则有值,没匹配的以null值取代。
  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. LEFT OUTER JOIN test_b ON test_a.name = test_b.name   
222

D. Left outer join on where

产生在A表中有而在B表中没有的集合。

  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. LEFT OUTER JOIN test_b ON test_a.name = test_b.name  
  6. WHERE  
  7.     test_b.name IS NULL   
222

E. RIGHT OUTER JOIN

产生表B的完全集,而A表中匹配的则有值,没匹配的以null值取代。
  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. RIGHT OUTER JOIN test_b ON test_a.name = test_b.name   
222

F. right outer join on where

产生在B表中有而在A表中没有的集合。
  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. RIGHT OUTER JOIN test_b ON test_a.name = test_b.name  
  6. WHERE  
  7.     test_a.name IS NULL   
222

G. FULL OUTER JOIN WHERE

产生(A表中有但B表没有)和(B表中有但A表中没有)的数据集。
  1. SELECT  
  2.     *  
  3. FROM  
  4.     test_a  
  5. FULL OUTER JOIN test_b ON test_a.name = test_b.name  
  6. WHERE  
  7.     test_a.name IS NULL  
  8. OR test_b.name IS NULL   
222

H. cross join

表A和表B的数据进行一个N*M的组合,即笛卡尔积(交差集)。一般来说,我们很少用到这个语法。因为这种集合的使用对于性能来说非常危险,尤其是表很大。这里就不做介绍了…
最后总结一下;
1.INNER JOIN 产生的结果是AB的交集
2.LEFT [OUTER] JOIN 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。
3.RIGHT [OUTER] JOIN 产生表B的完全集,而A表中匹配的则有值,没有匹配的则以null值取代。
4.FULL [OUTER] JOIN 产生A和B的并集。对于没有匹配的记录,则会以null做为值。
5. CROSS JOIN 把表A和表B的数据进行一个N*M的组合,即笛卡尔积。产生N*M条记录,在开发过程中我们肯定是要过滤数据,所以这种很少用。
### 不同SQL连接类型的定义与区别 #### 定义与基本功能 在关系型数据库中,`JOIN` 是一种用于组合两个或多个表的数据的操作。通过指定条件,可以从不同的表中提取所需的信息。 - **INNER JOIN(内连接)** `INNER JOIN` 返回的结果集仅包含那些满足连接条件的记录。换句话说,只有当两张表中的数据能够匹配上时,才会被返回[^2]。如果某张表中有不匹配的行,则这些行不会出现在最终结果集中。 - **LEFT JOIN(左外连接)** 左外连接会返回左边表 (`FROM` 子句后面的第一个表) 所有的记录以及右边表中符合条件的记录;对于右边表中没有对应匹配项的情况,在结果集中对应的字段会被填充为 NULL 值[^3]。 - **RIGHT JOIN(右外连接)** 右外连接的行为类似于左外连接,但它优先考虑的是右侧表(`ON`关键字后的第二个表),即它将保留右侧表所有的记录,并补充左侧表中存在的匹配部分或者用NULL填补缺失的部分[^4]。 #### 使用方法举例 以下是每种类型的具体应用实例: ```sql -- INNER JOIN 示例 SELECT * FROM employees e INNER JOIN departments d ON e.department_id = d.id; ``` 上述语句表示从员工(employee) 表和部门(department) 表里选出所有有共同 department_id 的条目。 ```sql -- LEFT JOIN 示例 SELECT students.name, classes.class_name FROM students LEFT JOIN classes ON students.class_id = classes.id; ``` 此查询显示学生的名字及其所属班级名称。即使某些学生的 class_id 并不存在于classes表之中,他们仍然会在输出列表里面出现,只是class_name列为空(NULL)。 ```sql -- RIGHT JOIN 示例 SELECT products.product_name, suppliers.supplier_name FROM products RIGHT JOIN suppliers ON products.supplier_id = suppliers.id; ``` 这里我们获取产品名连同一个供应商名字。如果有任何供应者未提供具体的产品信息,那么相应位置上的product_name将是null值。 #### 图解差异 为了更直观理解这几种连接方式之间的差别,可以通过图形化的方式来展示它们的工作原理。通常情况下,可以用Venn Diagrams来代表各个集合间的关系。例如,下图展示了四种主要形式如何相互作用并影响最终得到的数据子集[^5]: ![Join Types](https://i.imgur.com/yourimage.png) 请注意实际链接可能有所不同,请自行查找合适的图片资源替换占位符URL地址。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值