我使用Mysql已经有一段时间了,我对三张桌子上的简单LEFT JOIN的结果感到很困惑。
我有以下三个表(我创建了一个示例,以缩小范围)
a)人
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| PersonID | int(11) | NO | PRI | NULL | auto_increment |
| Name | varchar(50) | YES | | NULL | |
| Age | int(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
b)person_fav_artists
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| FavInterpretID | int(10) | NO | PRI | NULL | auto_increment |
| PersonID | int(10) | NO | | 0 | |
| Interpret | varchar(100) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
c)person_fav_movies
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| FavMovieID | int(10) | NO | PRI | NULL | auto_increment |
| PersonID | int(10) | NO | | 0 | |
| Movie | varchar(100) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
我的示例表用于将任意数量的艺术家和电影存储到一个人。 天气这种意义与否并不重要,因为它只是一个简单的例子。
现在我在表格中有以下数据:
mysql> SELECT * FROM persons;
+----------+------+------+
| PersonID | Name | Age |
+----------+------+------+
| 1 | Jeff | 22 |
| 2 | Lisa | 15 |
| 3 | Jon | 30 |
+----------+------+------+
mysql> SELECT * FROM person_fav_artists;
+----------------+----------+----------------+
| FavInterpretID | PersonID | Interpret |
+----------------+----------+----------------+
| 1 | 1 | Linkin Park |
| 2 | 1 | Muse |
| 3 | 2 | Madonna |
| 4 | 2 | Katy Perry |
| 5 | 2 | Britney Spears |
| 6 | 1 | Fort Minor |
| 7 | 1 | Jay Z |
+----------------+----------+----------------+
mysql> SELECT * FROM person_fav_movies;
+------------+----------+-------------------+
| FavMovieID | PersonID | Movie |
+------------+----------+-------------------+
| 1 | 1 | American Pie 1 |
| 2 | 1 | American Pie 2 |
| 3 | 1 | American Pie 3 |
| 4 | 3 | A Game of Thrones |
| 5 | 3 | Eragon |
+------------+----------+-------------------+
现在我只是使用以下查询加入表格:
Select * FROM persons
LEFT JOIN person_fav_artists USING (PersonID)
LEFT JOIN person_fav_movies USING (PersonID);
返回以下结果:
+----------+------+------+----------------+----------------+------------+-------------------+
| PersonID | Name | Age | FavInterpretID | Interpret | FavMovieID | Movie |
+----------+------+------+----------------+----------------+------------+-------------------+
| 1 | Jeff | 22 | 1 | Linkin Park | 1 | American Pie 1 |
| 1 | Jeff | 22 | 1 | Linkin Park | 2 | American Pie 2 |
| 1 | Jeff | 22 | 1 | Linkin Park | 3 | American Pie 3 |
| 1 | Jeff | 22 | 2 | Muse | 1 | American Pie 1 |
| 1 | Jeff | 22 | 2 | Muse | 2 | American Pie 2 |
| 1 | Jeff | 22 | 2 | Muse | 3 | American Pie 3 |
| 1 | Jeff | 22 | 6 | Fort Minor | 1 | American Pie 1 |
| 1 | Jeff | 22 | 6 | Fort Minor | 2 | American Pie 2 |
| 1 | Jeff | 22 | 6 | Fort Minor | 3 | American Pie 3 |
| 1 | Jeff | 22 | 7 | Jay Z | 1 | American Pie 1 |
| 1 | Jeff | 22 | 7 | Jay Z | 2 | American Pie 2 |
| 1 | Jeff | 22 | 7 | Jay Z | 3 | American Pie 3 |
| 2 | Lisa | 15 | 3 | Madonna | NULL | NULL |
| 2 | Lisa | 15 | 4 | Katy Perry | NULL | NULL |
| 2 | Lisa | 15 | 5 | Britney Spears | NULL | NULL |
| 3 | Jon | 30 | NULL | NULL | 4 | A Game of Thrones |
| 3 | Jon | 30 | NULL | NULL | 5 | Eragon |
+----------+------+------+----------------+----------------+------------+-------------------+
17 rows in set (0.00 sec)
到目前为止一切顺利。 我现在的问题是,如果对于'杰夫'这个人'返回'12'行是“正常的”,尽管他只有四个'艺术家'和三个'电影'分配给他。 我想我可能理解为什么结果是这样的,但我认为返回如此多的Rows以获得如此少的实际数据是非常愚蠢的。
我的查询是否有问题或是故意这种行为?
我希望得到的结果如下(仅适用于Jeff):
+----------+------+------+----------------+----------------+------------+-------------------+
| PersonID | Name | Age | FavInterpretID | Interpret | FavMovieID | Movie |
+----------+------+------+----------------+----------------+------------+-------------------+
| 1 | Jeff | 22 | 1 | Linkin Park | 1 | American Pie 1 |
| 1 | Jeff | 22 | 2 | Muse | 2 | American Pie 2 |
| 1 | Jeff | 22 | 3 | Fort Minor | 3 | American Pie 3 |
| 1 | Jeff | 22 | 4 | Jay Z | 1 | NULL | <- 'American Pie 1/2/3' would be OK as well.
+----------+------+------+----------------+----------------+------------+-------------------+
感谢您的帮助!
答案 0 :(得分:1)
查询或结果没有错,它只是返回所有可能的组合。如果数据量很大,一种选择是分成两个单独的查询。
答案 1 :(得分:0)
此行为是故意的。
你现在有了所有可能的组合。
答案 2 :(得分:0)
我认为这是正常的,因为它正在拍摄所有电影和收藏艺术家的组合。我认为这就是加入的方式。
答案 3 :(得分:0)
您正在使用12条记录获得正确的结果,因为这是您要求数据的正确元组。我不确定你为什么要加入这三个表,因为这两个相关的表并不是同一类型的数据。我建议你选择人和人。电影,然后你可以联合人和&amp;艺术家,因为你的工会会希望列相同,我建议添加一个类型来区分艺术家和电影,然后好名字应该只是一个字符串_值
答案 4 :(得分:0)
尝试将INFT JOIN替换为LEFT JOIN:
SELECT *
FROM persons
INNER JOIN person_fav_artists USING (PersonID)
INNER JOIN person_fav_movies USING (PersonID);