通过自联接替换嵌套的选择查询

时间:2013-02-27 10:30:21

标签: mysql sql select self-join

我最近在这里问了一个关于SQL查询的问题:Trouble wrapping head around complex SQL delete query

我现在明白,我正在尝试做的事情太复杂了,无法通过单个查询甚至多个查询来实现,而无需在某种程度上保持结果。因此我决定创建一个bash脚本(最终结果将与cronjob有关,因此bash是最直接的选择)。

考虑下表:

AssociatedClient:

+-----------+-----------------+
| Client_id | Registration_id |
+-----------+-----------------+
|         2 |               2 | 
|         3 |               2 | 
|         3 |               4 | 
|         4 |               5 | 
|         3 |               6 | 
|         5 |               6 | 
|         3 |               8 | 
|         8 |               9 | 
|         7 |              10 | 
+-----------------------------+

我想要做的是选择所有Registration_id s Client_id 列表中的 Client_id特定 Registration_id相关联。

虽然我对SQL很不错,但我发现这个查询相对容易:

SELECT `Registration_id` FROM `AssociatedClient` ac1
WHERE ac1.`Client_id` IN
                      (SELECT `Client_id` FROM `AssociatedClient` ac2 
                       WHERE ac2.`Registration_id` = $reg_id);

其中$reg_id只是一个bash变量。

这可行,但我希望看到自我加入,因为它看起来更好,尤其是在出现大量字符混乱的bash脚本中。我担心我的SQL技能不会达到那么远。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你应该能够像这样做一个简单的自我加入:

SELECT ac1.registration_id
FROM associatedclient ac1
JOIN associatedclient ac2 ON ac2.client_id = ac1.client_id
WHERE ac2.registration_id = $reg_id

所以你正在做的是扫描一次表,将它连接到client_id匹配的地方。然后,您将连接的行限制为表的第二个版本具有特定ID的那些行,在第一个表上留下连接的不同排列,然后从这些行中选择registration_id。

因此,给定变量值为6的示例,请尝试运行以下语句:

SELECT 
  ac1.client_id AS client_id_1
, ac1.registration_id AS reg_id_1
, ac2.client_id AS client_id_2
, ac2.registration_id AS reg_id_2
FROM associatedclient ac1
JOIN associatedclient ac2 ON ac1.client_id = ac2.client_id

你会注意到完整的连接集。然后尝试添加WHERE限制并注意哪些行返回。然后最后选择你想要的列。

您可以查看我设置的SQLFiddle,其值为6