作为一个视觉型的人,更喜欢以图形的方式来理解事物。在网上寻找了很长时间,试图找到一个满意的SQLJOIN操作的图形表示,但发现要么图形不完整(没有包含所有可能的JOIN操作),要么质量很差。因此,决定自己创建一个,并写一篇文章来介绍它。
在这篇文章中,将讨论七种不同的从两个关系表中返回数据的方法。将排除交叉JOIN和自引用JOIN。将要讨论的七种JOIN操作如下所示:
为了本文的目的,将5、6和7分别称为LEFT EXCLUDING JOIN、RIGHT EXCLUDING JOIN和OUTER EXCLUDING JOIN。有些人可能会争论说5、6和7并不是真正的JOIN操作,但为了简单起见,仍然将这些称为JOIN,因为在这些查询中使用了SQLJOIN(但通过WHERE子句排除了一些记录)。
这是最简单、最易理解的JOIN操作,也是最常见的。这个查询将返回左表(表A)中所有在右表(表B)中有匹配记录的记录。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key
这个查询将返回左表(表A)中的所有记录,无论这些记录是否在右表(表B)中有匹配的记录。它还将返回右表中的任何匹配记录。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
这个查询将返回右表(表B)中的所有记录,无论这些记录是否在左表(表A)中有匹配的记录。它还将返回左表中的任何匹配记录。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
这个JOIN也可以被称为FULL OUTER JOIN或FULL JOIN。这个查询将返回两个表中的所有记录,将左表(表A)中的记录与右表(表B)中的记录进行匹配。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
这个查询将返回左表(表A)中所有在右表(表B)中没有匹配记录的记录。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL
这个查询将返回右表(表B)中所有在左表(表A)中没有匹配记录的记录。这个JOIN操作的写法如下:
SELECT
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL
这个查询将返回左表(表A)中的所有记录和右表(表B)中所有没有匹配的记录。还没有使用过这种类型的JOIN,但其他类型的JOIN经常使用。这个JOIN操作的写法如下:
SELECT
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_A和Table_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)
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的说明,内部连接的记录首先返回,其次是右连接的记录,然后是左连接的记录(至少在MicrosoftSQLServer中是这样;当然,这是在没有使用任何ORDER BY语句的情况下)。
可以访问Wikipedia上的相关文章了解更多信息:(不过,该条目没有图形表示)。