我很久以來一直在使用Mysql,並且對三個表上簡單的LEFT JOIN的結果感到困惑。三個表的Mysql LEFT JOIN返回到許多行
我有以下三個表(I創建了一個例子,將它縮小)
一個)人
+----------+-------------+------+-----+---------+----------------+
| 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 |
+------------+----------+-------------------+
現在i'm簡單地用下面的查詢連接表:
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'行'是正常的',儘管他只有四個'藝術家'和三部'電影'分配給他。 我想我可能會理解爲什麼結果是如此,但我認爲爲實際數據太少而返回太多行是相當愚蠢的。
那麼,我的查詢有什麼問題,或者這是故意的行爲?
結果我倒是想有,會象(僅適用於傑夫)以下:
+----------+------+------+----------------+----------------+------------+-------------------+
| 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.
+----------+------+------+----------------+----------------+------------+-------------------+
感謝您的幫助!
謝謝您的回答! 我已經認爲這是「正確」的結果,因爲它返回所有可能的組合。 關於你的問題: 我加入表格在C#中創建一個對象「人物」,然後列出哪些包含「電影」和「藝術家」。 我正在使用此查詢來創建整個對象,因此我將所有內容連接在一起。 也許這將是更聰明的做它分開,但後來我有更多的查詢... – user1288392 2012-03-23 14:57:07
如果您使用的C#對象,有能力「過濾」的記錄,你當然可以使用過濾器數據並將其應用於您的對象/視圖,然後重新過濾並將其應用於其他對象/視圖。這會讓你的SQL拉一拉,但我不建議。從第三個表加入數據所需的時間與第二個語句相同,因爲你的第一個表被緩存了。 – 2012-03-23 15:32:01
是的,你說得對,我的C#對象是從Mysql-Query中「過濾」結果的。這意味着重複的行將被忽略。 我不舒服我理解你的答案的第二部分。你的意思是我應該使用更多的查詢,而不是像我在我的例子中完成的一樣大嗎?這意味着我必須爲電影和藝術家創建一個單獨的查詢。 – user1288392 2012-03-23 16:42:57