自我结合的内部运作方式与WHERE相结合

时间:2019-05-01 10:42:45

标签: sql inner-join self-join

我有一张桌子

contacts
---------
contact_id  company         contact
1000000001  Village Toys    John Smith
1000000002  Kids Place      Michelle Green
1000000003  Fun4All         Jim Jones
1000000004  Fun4All         Denise L. Stephens
1000000005  The Toy Store   Kim Howard

我想找到Jim Jones所服务的公司的所有联系人。 这是正确的设置。

1000000003  Fun4All         Jim Jones
1000000004  Fun4All         Denise L. Stephens

我使用了子查询来解决这个问题,但我得到了正确的结果。 然后,我尝试在“ Jim Jones”上的where处进行自我内部联接,但得到的结果我无法理解。

SELECT tableA.contact_id, tableA.company, tableA.contact
FROM company AS tableA
JOIN company AS tableB
ON tableA.company = tableB.company
WHERE tableB.contact = 'Jim Jones'

我得到正确的结果集

1000000003  Fun4All         Jim Jones
1000000004  Fun4All         Denise L. Stephens

但是如果我使用

更改了WHERE
WHERE tableA.contact = 'Jim Jones'

我明白了

1000000003  Fun4All         Jim Jones
1000000003  Fun4All         Jim Jones

为什么要这么做?这是如何工作的? 我整夜试图解决这个问题。 但这使我难以理解。我在Google上找到的示例让我不敢理解。

数据库(在我的问题中,我更改了列名称以进行澄清)

http://forta.com/books/0672336073/TeachYourselfSQL_SQLite.zip
http://forta.com/books/0672336073/TeachYourselfSQL_Oracle.zip
http://forta.com/books/0672336073/TeachYourselfSQL_MySQL.zip
http://forta.com/books/0672336073/TeachYourselfSQL_MicrosoftSQLServer.zip
http://forta.com/books/0672336073/TeachYourselfSQL_Access2007.zip
http://forta.com/books/0672336073/TeachYourselfSQL_OpenOfficeBase.zip

2 个答案:

答案 0 :(得分:2)

要获取说明,请执行以下操作:

1)使其他表(自连接)可见,以查看不带where子句的连接时实际获得的结果:

  

选择A.contactid,A.company,A.contact,B.contactid,B.company,B.contact   从联系人A   内部联接触点B   在A.company = B.company

self joined tables

2)现在添加您的WHERE子句,并将A.contact与B.contact交换以查看会发生什么情况

答案 1 :(得分:1)

您可以使用这种方法获得所需的结果。

SELECT *
FROM   TableName
WHERE  company IN (SELECT company
                   FROM   TableName
                   WHERE  contact = 'Jim Jones')  

在查询中,如果要将WHERE tableB.contact = 'Jim Jones'更改为WHERE tableA.contact = 'Jim Jones',则也必须更改SELECT语句。

SELECT tableA.contact_id, tableA.company, tableA.contact
FROM company AS tableA
JOIN company AS tableB
ON tableA.company = tableB.company
WHERE tableB.contact = 'Jim Jones'

SELECT tableB.contact_id, tableB.company, tableB.contact
FROM company AS tableA
JOIN company AS tableB
ON tableA.company = tableB.company
WHERE tableA.contact = 'Jim Jones'

您必须执行此操作,因为您正在从此结果中进行过滤。
(您正在使用company列进行自我加入。)

SELECT *
FROM company AS tableA
JOIN company AS tableB
ON tableA.company = tableB.company

+-----------------+----------------+---------------------+----------------+----------------+---------------------+
| contact_id (A)  |  company (A)   |     contact (A)     | contact_id (B) |  company (B)   |     contact (B)     |
+-----------------+----------------+---------------------+----------------+----------------+---------------------+
|      1000000001 | Village Toys   | John Smith          |     1000000001 | Village Toys   | John Smith          |
|      1000000002 | Kids Place     | Michelle Green      |     1000000002 | Kids Place     | Michelle Green      |
|      1000000003 | Fun4All        | Jim Jones           |     1000000003 | Fun4All        | Jim Jones           |
|      1000000004 | Fun4All        | Denise L. Stephens  |     1000000003 | Fun4All        | Jim Jones           |
|      1000000003 | Fun4All        | Jim Jones           |     1000000004 | Fun4All        | Denise L. Stephens  |
|      1000000004 | Fun4All        | Denise L. Stephens  |     1000000004 | Fun4All        | Denise L. Stephens  |
|      1000000005 | The Toy Store  | Kim Howard          |     1000000005 | The Toy Store  | Kim Howard          |
+-----------------+----------------+---------------------+----------------+----------------+---------------------+