自联接返回的行数超出预期

时间:2015-07-26 16:21:00

标签: mysql inner-join

我是自我加入的新手,并编写了以下示例表:

+-----------+-------------+
| name      | location    |
+-----------+-------------+
| Robert    | Guadalajara |
| Manuel    | Guadalajara |
| Dalia     | Guadalajara |
| Alejandra | Guadalajara |
| Luis      | Guadalajara |
| Monica    | Guadalajara |
| Claudia   | Guadalajara |
| Scartlet  | Guadalajara |
| Sergio    | Guadalajara |
| Rick      | Mexico City |
| Rene      | Mexico City |
| Ramon     | Culiacan    |
| Junior    | Culiacan    |
| Kasandra  | Culiacan    |
| Emma      | Culiacan    |
| Johnatha  | Dunedin     |
| Miriam    | Largo       |
| Julie     | Largo       |
+-----------+-------------+

18行

我想运行一个简单的查询,使用以下查询匹配具有相同位置的人:

SELECT users1.name, users1.location, users2.name, users2.location
FROM users users1, users users2
WHERE users1.location = users2.location;

我的期望:

+-----------+-------------++-----------+-------------+                  
| name      | location    || name      | location    |
+-----------+-------------++-----------+-------------+
| Robert    | Guadalajara || Robert    | Guadalajara |
| Manuel    | Guadalajara || Manuel    | Guadalajara |
| Dalia     | Guadalajara || Dalia     | Guadalajara |
| Alejandra | Guadalajara || Alejandra | Guadalajara |
| Luis      | Guadalajara || Luis      | Guadalajara |
| Monica    | Guadalajara || Monica    | Guadalajara |
| Claudia   | Guadalajara || Claudia   | Guadalajara |
| Scartlet  | Guadalajara || Scartlet  | Guadalajara |
| Sergio    | Guadalajara || Sergio    | Guadalajara |
| Rick      | Mexico City || Rick      | Mexico City |
| Rene      | Mexico City || Rene      | Mexico City |
| Ramon     | Culiacan    || Ramon     | Culiacan    |
| Junior    | Culiacan    || Junior    | Culiacan    |
| Kasandra  | Culiacan    || Kasandra  | Culiacan    |
| Emma      | Culiacan    || Emma      | Culiacan    |
| Johnatha  | Dunedin     || Johnatha  | Dunedin     |
| Miriam    | Largo       || Miriam    | Largo       |
| Julie     | Largo       || Julie     | Largo       |
+-----------+-------------++-----------+-------------+

我得到了什么:

+-----------+-------------+-----------+-------------+
| name      | location    | name      | location    |
+-----------+-------------+-----------+-------------+
| Robert    | Guadalajara | Robert    | Guadalajara |
| Manuel    | Guadalajara | Robert    | Guadalajara |
| Dalia     | Guadalajara | Robert    | Guadalajara |
| Alejandra | Guadalajara | Robert    | Guadalajara |
| Luis      | Guadalajara | Robert    | Guadalajara |
| Monica    | Guadalajara | Robert    | Guadalajara |
| Claudia   | Guadalajara | Robert    | Guadalajara |
| Scartlet  | Guadalajara | Robert    | Guadalajara |
| Sergio    | Guadalajara | Robert    | Guadalajara |
| Robert    | Guadalajara | Manuel    | Guadalajara |
| Manuel    | Guadalajara | Manuel    | Guadalajara |
| Dalia     | Guadalajara | Manuel    | Guadalajara |
| Alejandra | Guadalajara | Manuel    | Guadalajara |
| Luis      | Guadalajara | Manuel    | Guadalajara |
| Monica    | Guadalajara | Manuel    | Guadalajara |
| Claudia   | Guadalajara | Manuel    | Guadalajara |
| Scartlet  | Guadalajara | Manuel    | Guadalajara |
| Sergio    | Guadalajara | Manuel    | Guadalajara |
| Robert    | Guadalajara | Dalia     | Guadalajara |
| Manuel    | Guadalajara | Dalia     | Guadalajara |
| Dalia     | Guadalajara | Dalia     | Guadalajara |
| Alejandra | Guadalajara | Dalia     | Guadalajara |
| Luis      | Guadalajara | Dalia     | Guadalajara |
| Monica    | Guadalajara | Dalia     | Guadalajara |
| Claudia   | Guadalajara | Dalia     | Guadalajara |
| Scartlet  | Guadalajara | Dalia     | Guadalajara |
| Sergio    | Guadalajara | Dalia     | Guadalajara |
| Robert    | Guadalajara | Alejandra | Guadalajara |
| Manuel    | Guadalajara | Alejandra | Guadalajara |
| Dalia     | Guadalajara | Alejandra | Guadalajara |
| Alejandra | Guadalajara | Alejandra | Guadalajara |
| Luis      | Guadalajara | Alejandra | Guadalajara |
| Monica    | Guadalajara | Alejandra | Guadalajara |
| Claudia   | Guadalajara | Alejandra | Guadalajara |
| Scartlet  | Guadalajara | Alejandra | Guadalajara |
| Sergio    | Guadalajara | Alejandra | Guadalajara |
| Robert    | Guadalajara | Luis      | Guadalajara |
| Manuel    | Guadalajara | Luis      | Guadalajara |
| Dalia     | Guadalajara | Luis      | Guadalajara |
| Alejandra | Guadalajara | Luis      | Guadalajara |
| Luis      | Guadalajara | Luis      | Guadalajara |
| Monica    | Guadalajara | Luis      | Guadalajara |
| Claudia   | Guadalajara | Luis      | Guadalajara |
| Scartlet  | Guadalajara | Luis      | Guadalajara |
| Sergio    | Guadalajara | Luis      | Guadalajara |
| Robert    | Guadalajara | Monica    | Guadalajara |
| Manuel    | Guadalajara | Monica    | Guadalajara |
| Dalia     | Guadalajara | Monica    | Guadalajara |
| Alejandra | Guadalajara | Monica    | Guadalajara |
| Luis      | Guadalajara | Monica    | Guadalajara |
| Monica    | Guadalajara | Monica    | Guadalajara |
| Claudia   | Guadalajara | Monica    | Guadalajara |
| Scartlet  | Guadalajara | Monica    | Guadalajara |
| Sergio    | Guadalajara | Monica    | Guadalajara |
| Robert    | Guadalajara | Claudia   | Guadalajara |
| Manuel    | Guadalajara | Claudia   | Guadalajara |
| Dalia     | Guadalajara | Claudia   | Guadalajara |
| Alejandra | Guadalajara | Claudia   | Guadalajara |
| Luis      | Guadalajara | Claudia   | Guadalajara |
| Monica    | Guadalajara | Claudia   | Guadalajara |
| Claudia   | Guadalajara | Claudia   | Guadalajara |
| Scartlet  | Guadalajara | Claudia   | Guadalajara |
| Sergio    | Guadalajara | Claudia   | Guadalajara |
| Robert    | Guadalajara | Scartlet  | Guadalajara |
| Manuel    | Guadalajara | Scartlet  | Guadalajara |
| Dalia     | Guadalajara | Scartlet  | Guadalajara |
| Alejandra | Guadalajara | Scartlet  | Guadalajara |
| Luis      | Guadalajara | Scartlet  | Guadalajara |
| Monica    | Guadalajara | Scartlet  | Guadalajara |
| Claudia   | Guadalajara | Scartlet  | Guadalajara |
| Scartlet  | Guadalajara | Scartlet  | Guadalajara |
| Sergio    | Guadalajara | Scartlet  | Guadalajara |
| Robert    | Guadalajara | Sergio    | Guadalajara |
| Manuel    | Guadalajara | Sergio    | Guadalajara |
| Dalia     | Guadalajara | Sergio    | Guadalajara |
| Alejandra | Guadalajara | Sergio    | Guadalajara |
| Luis      | Guadalajara | Sergio    | Guadalajara |
| Monica    | Guadalajara | Sergio    | Guadalajara |
| Claudia   | Guadalajara | Sergio    | Guadalajara |
| Scartlet  | Guadalajara | Sergio    | Guadalajara |
| Sergio    | Guadalajara | Sergio    | Guadalajara |
| Rick      | Mexico City | Rick      | Mexico City |
| Rene      | Mexico City | Rick      | Mexico City |
| Rick      | Mexico City | Rene      | Mexico City |
| Rene      | Mexico City | Rene      | Mexico City |
| Ramon     | Culiacan    | Ramon     | Culiacan    |
| Junior    | Culiacan    | Ramon     | Culiacan    |
| Kasandra  | Culiacan    | Ramon     | Culiacan    |
| Emma      | Culiacan    | Ramon     | Culiacan    |
| Ramon     | Culiacan    | Junior    | Culiacan    |
| Junior    | Culiacan    | Junior    | Culiacan    |
| Kasandra  | Culiacan    | Junior    | Culiacan    |
| Emma      | Culiacan    | Junior    | Culiacan    |
| Ramon     | Culiacan    | Kasandra  | Culiacan    |
| Junior    | Culiacan    | Kasandra  | Culiacan    |
| Kasandra  | Culiacan    | Kasandra  | Culiacan    |
| Emma      | Culiacan    | Kasandra  | Culiacan    |
| Ramon     | Culiacan    | Emma      | Culiacan    |
| Junior    | Culiacan    | Emma      | Culiacan    |
| Kasandra  | Culiacan    | Emma      | Culiacan    |
| Emma      | Culiacan    | Emma      | Culiacan    |
| Johnatha  | Dunedin     | Johnatha  | Dunedin     |
| Miriam    | Largo       | Miriam    | Largo       |
| Julie     | Largo       | Miriam    | Largo       |
| Miriam    | Largo       | Julie     | Largo       |
| Julie     | Largo       | Julie     | Largo       |
+-----------+-------------+-----------+-------------+

有人可以向我解释为什么我从建议的解决方案中得到这个结果?我想知道这是如何以及为什么会产生的。

感谢。

2 个答案:

答案 0 :(得分:2)

您在位置匹配,多次出现。这将乘以您当前的结果。

您的预期结果是姓名加入:

SELECT users1.name, users1.location, users2.name, users2.location
FROM users users1
INNER JOIN users users2 ON users1.name = users2.name;

查询的工作原理:

在数据集中,WHERE中的列是匹配的。这等同于JOIN:

users1.name

现在更常用的语法是哪种。两个查询都是相同的,但是通过JOIN,它变得更具可读性和灵活性。

JOIN中的匹配是在users2.name等于INNER users users2 ON users1.location = users2.location; 的情况下进行的。然后显示找到的结果:

  

|罗伯特|瓜达拉哈拉|

例如。

如果使用location而不是name运行查询:

+-----------+-------------+----+
| name      | location    | ID |
+-----------+-------------+----+
| Robert    | Guadalajara | 1  |
| Manuel    | Guadalajara | 2  |

SQL匹配位置。因此,对于更短的更易读的例子,想象一下这个短表。添加列ID以显示结果的收集方式:

 | Robert    | Guadalajara | 1  |
 | Manuel    | Guadalajara | 1  |

这在位置匹配,发生两次:

  

Id 1与Id 1和Id 2(使用位置)匹配:导致2个位置记录:

 | Robert    | Guadalajara | 2  |
 | Manuel    | Guadalajara | 2  |
  

Id 2与Id 1和Id 2(使用位置)匹配:导致2个位置记录:

| Robert    | Guadalajara | 1  |
| Manuel    | Guadalajara | 1  |
| Robert    | Guadalajara | 2  |
| Manuel    | Guadalajara | 2  |

那么结果将是:

grep

因此你的原始记录会倍增。

答案 1 :(得分:2)

要获得您期望的结果,您需要加入名称和位置:

SELECT users1.name, users1.location, users2.name, users2.location
FROM users users1
JOIN users users2 ON users1.location = users2.location 
                 AND users1.name = users2.name ;

在问题中你说你希望结果匹配具有相同位置的人,如果是这种情况,那么你想要的是:

SELECT users1.name, users1.location, users2.name, users2.location
FROM users users1
JOIN users users2 ON users1.location = users2.location 
                 AND users1.name <> users2.name ;

有关结果的示例,请参阅此sample SQL Fiddle

请注意,第二个查询将复制结果,因为每个匹配都会有相应的对称匹配(Robert和Luis匹配,但也有Luis和Robert)。我认为以下查询应该解决这个问题:

SELECT users1.name, users1.location, users2.name, users2.location
FROM users users1
JOIN users users2 ON users1.location = users2.location 
AND CASE WHEN users1.name < users2.name THEN users1.name ELSE users2.name END <> users2.name;

Sample SQL Fiddle用于上次查询。