65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Join 的可视化表示

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (450投票s)

2009年2月4日

CPOL

3分钟阅读

viewsIcon

4078453

downloadIcon

14285

本文以视觉方式描述了 SQL 连接,以及编写可视化连接的最有效方法。

背景

我是一个很注重视觉的人。图片似乎更能说明问题。我在互联网上搜索了关于 SQL JOIN 的良好图形表示,但我找不到任何让我满意的。有些图表很好,但缺乏完整性(它们没有包含所有可能的 JOIN),有些则非常糟糕。所以,我决定创建自己的并写一篇关于它的文章。

使用代码

我将讨论七种可以从两个关系表中返回数据的方法。我将排除交叉连接和自引用连接。我将讨论的七种连接如下所示:

  1. INNER JOIN
  2. LEFT JOIN
  3. RIGHT JOIN
  4. OUTER JOIN
  5. LEFT JOIN EXCLUDING INNER JOIN
  6. RIGHT JOIN EXCLUDING INNER JOIN
  7. OUTER JOIN EXCLUDING INNER JOIN

为了本文的目的,我将把 5、6 和 7 分别称为 LEFT EXCLUDING JOINRIGHT EXCLUDING JOINOUTER EXCLUDING JOIN。有些人可能会争辩说,5、6 和 7 实际上并没有连接这两个表,但为了简单起见,我仍将它们称为连接,因为您在每个查询中使用 SQL 连接(但使用 WHERE 子句排除一些记录)。

Inner JOIN

Visual_SQL_Joins/INNER_JOIN.png

这是最简单、最容易理解的连接,也是最常见的。此查询将返回左表(表 A)中所有在右表(表 B)中具有匹配记录的记录。此连接的编写方式如下:

SELECT <select_list> 
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key

Left JOIN

Visual_SQL_Joins/LEFT_JOIN.png

此查询将返回左表(表 A)中的所有记录,无论这些记录在右表(表 B)中是否有匹配项。它还将返回右表中的任何匹配记录。此连接的编写方式如下:

SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key

Right JOIN

Visual_SQL_Joins/RIGHT_JOIN.png

此查询将返回右表(表 B)中的所有记录,无论这些记录在左表(表 A)中是否有匹配项。它还将返回左表中的任何匹配记录。此连接的编写方式如下:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key

Outer JOIN

Visual_SQL_Joins/FULL_OUTER_JOIN.png

此连接也可以称为 FULL OUTER JOINFULL JOIN。此查询将返回两个表中的所有记录,连接左表(表 A)中与右表(表 B)中的记录匹配的记录。此连接的编写方式如下:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key

Left Excluding JOIN

Visual_SQL_Joins/LEFT_EXCLUDING_JOIN.png

此查询将返回左表(表 A)中所有与右表(表 B)中任何记录都不匹配的记录。此连接的编写方式如下:

SELECT <select_list> 
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Right Excluding JOIN

Visual_SQL_Joins/RIGHT_EXCLUDING_JOIN.png

此查询将返回右表(表 B)中所有与左表(表 A)中任何记录都不匹配的记录。此连接的编写方式如下:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL

Outer Excluding JOIN

Visual_SQL_Joins/OUTER_EXCLUDING_JOIN.png

此查询将返回左表(表 A)中的所有记录和右表(表 B)中的所有不匹配的记录。我还没有使用这种类型的连接的需求,但其他所有连接我都经常使用。此连接的编写方式如下:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL OR B.Key IS NULL

示例

假设我们有两个表,Table_ATable_B。这些表中的数据如下所示:

TABLE_A
  PK Value
---- ----------
   1 FOX
   2 COP
   3 TAXI
   6 WASHINGTON
   7 DELL
   5 ARIZONA
   4 LINCOLN
  10 LUCENT

TABLE_B
  PK Value
---- ----------
   1 TROT
   2 CAR
   3 CAB
   6 MONUMENT
   7 PC
   8 MICROSOFT
   9 APPLE
  11 SCOTCH

七种连接的结果如下所示:

-- INNER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
       B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7

(5 row(s) affected)
-- LEFT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
  10 LUCENT     NULL       NULL

(8 row(s) affected)
-- RIGHT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(8 row(s) affected)
-- OUTER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(11 row(s) affected)
-- LEFT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
  10 LUCENT     NULL       NULL
(3 row(s) affected)
-- RIGHT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(3 row(s) affected)
-- OUTER EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(6 row(s) affected)

关于 OUTER JOIN 的说明:内连接的记录首先返回,然后是右连接的记录,最后是左连接的记录(至少,这是我的 Microsoft SQL Server 的做法;当然,这是没有使用任何 ORDER BY 语句的情况下)。

您可以在维基百科文章中找到更多信息,请访问这里(但是,该条目没有图形)。

我还创建了一个备忘单,您可以在需要时打印出来。如果您右键单击下面的图像并选择“另存为...”,您将下载全尺寸图像。

历史

  • 初始发布 - 02/03/2009。
  • 版本 1.0 - 02/04/2009 - 修复了备忘单和一些小错误。
© . All rights reserved.