簡體   English   中英

三個表的MySQL LEFT JOIN返回許多行

[英]Mysql LEFT JOIN of three tables returns to many Rows

我使用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)

到現在為止還挺好。 我的問題是,盡管“傑夫”只有四個“藝術家”和三個“電影”被分配給他,但是否會“返回”十二行是“正常的”。 我想我可能理解為什么會這樣,但是我認為返回如此多的行以獲取較少的實際數據是非常愚蠢的。

那么我的查詢有問題嗎?還是這種行為是故意的?

我想要的結果如下所示(僅適用於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.
+----------+------+------+----------------+----------------+------------+-------------------+

謝謝你的幫助!

查詢或結果沒有問題,它只是返回所有可能的組合。 如果數據量很大,一種選擇是將拆分為兩個單獨的查詢。

此行為是故意的。

  1. 您的第一個表有1列Jeff。
  2. 第二個表有4個Jeff列,因此聯接的表為1x4。
  3. 第三個表有3個Jeff列,因此聯接的表為1x4x3。

現在,您獲得了所有可能的組合。

我認為這很正常,因為它將所有收藏的電影和收藏的藝術家結合在一起。 我認為這就是加入的方式。

您將獲得12條記錄的正確結果,因為這是您查詢數據的方式正確的元組。 我不確定為什么將這3個表固有地連接在一起,因為2個相關表不是同一類型的數據。 我建議您選擇人物和電影,然后可以合並人物和藝術家,因為您的工會希望各列保持相同,我建議添加一種類型以區別於藝術家和電影,然后使用好聽的名稱只是作為一個string_value

嘗試用INNER JOIN替換LEFT JOIN為:

     SELECT * 
     FROM persons 
     INNER JOIN person_fav_artists USING (PersonID) 
     INNER JOIN person_fav_movies USING (PersonID); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM