2013-03-17 334 views
1

我有以下查詢是多次返回所有相同的行。MySQL查詢 - 加入問題

我需要連接2個表:註釋和項目對象,但無論我嘗試使用哪種方式,行都重複多次。

下面是當前查詢:

SELECT 
acx_comments.created_on AS 'Time', 
acx_project_objects.created_by_id AS `Created By`, 
acx_comments.body AS `Comment`, 
concat("http://www.example.com/projects/" , acx_project_objects.project_id , "/tasks/" , acx_project_objects.integer_field_1) AS URL 
FROM acx_comments, acx_project_objects 
LEFT JOIN acx_comments v 
ON v.parent_id = acx_project_objects.id 
WHERE acx_comments.id > 1500 AND acx_comments.id <= 1575 
ORDER BY acx_comments.created_on DESC 

目前的結果是這樣的:

時間/創建/評論/ URL

15時35分34秒/ 1 /測試點評X /網址X

15時35分34秒/ 1 /測試點評X /網址X

15時35分34秒/ 1 /測試點評X /網址X

15時35分34秒/ 1 /測試點評X /網址X

15時35分34秒/ 1 /測試點評X /網址X

15點35: 34/1 /測試註釋X /網址X

15時35分34秒/ 1 /測試點評X /網址X

正如你可以看到 - 它是同一個註釋多次打印。

我知道這是由於acx_comments.parent_id連接到acx_project_objects.id時有很多重複的事實 - 有很多註釋具有相同的父母id,因爲每個父母可以有多個註釋。但我只想按日期順序打印評論。

我找不出正確的Join方法來使它只打印每個評論一次。上面的代碼沒有給我按日期排序的評論列表(僅限於唯一)。

任何意見,將不勝感激,因爲我已經花了幾個小時,並不能找出解決方案。

謝謝!

順便說一句 - 我必須使用項目對象表,因爲它需要構造URL地址(請參閱concat函數)。如果你認爲我應該刪除該表 - 這是不可能的

+1

使用distinct關鍵字? – Sebas 2013-03-17 03:09:49

+1

以及有關混合逗號和ansi連接的信息,請查看該帖子:http://stackoverflow.com/a/11180050/1291428 – Sebas 2013-03-17 03:15:23

+0

對此查詢運行解釋計劃,我敢打賭你會看到錯誤的解決方案遠。 – Aaron 2013-03-17 03:31:52

回答

2
FROM acx_comments, acx_project_objects 
LEFT JOIN acx_comments v 
ON v.parent_id = acx_project_objects.id 

你在技術上加入兩次acx_comments。您的WHERE子句不包含任何JOIN條件,並且ON子句中的JOIN條件僅適用於您的LEFT JOIN中指定的「acx_comments v」。

我對於發生的事情的猜測是你在acx_comments和acx_project_objects之間創建了一個Cartesian Product,因爲它們在WHERE中沒有JOIN條件時以逗號分隔。然後你再次加入對acx_comments的混亂。

重寫你的FROM和LEFT JOIN,以便每個表只列出一次,並給它一個鏡頭。

SELECT 
v.created_on AS 'Time', 
o.created_by_id AS `Created By`, 
v.body AS `Comment`, 
concat("http://www.example.com/projects/" , o.project_id , "/tasks/" , o.integer_field_1) AS URL 
FROM acx_comments v 
LEFT JOIN acx_project_objects o 
ON v.parent_id = o.id 
WHERE v.id > 1500 AND v.id <= 1575 
ORDER BY v.created_on DESC 
+0

,做到了。謝謝! – 2013-03-17 04:15:39

+0

@DanielC不客氣!我感到不得不補充說,像這樣的情況正是爲什麼開發者應該始終明確指定JOIN關鍵字和條件。使用逗號分隔的JOIN表示法既快速又容易,但它會讓你打開這樣的錯誤。 – Aaron 2013-03-17 12:11:49

+0

謝謝,但是我不明白你的意思是明確指定JOIN關鍵字和條件。您的答案從FROM語句中刪除了其中一個表,並切換了連接表語句的順序。你能否用逗號分隔的JOIN符號來說明你的意思?我想確保我理解以後的查詢。謝謝! – 2013-03-18 00:45:08

1

您可以嘗試在註釋ID上使用MySQL的GROUP BY

SELECT 
    acx_comments.created_on 'Time', 
    acx_project_objects.created_by_id 'Created By', 
    acx_comments.body 'Comment', 
    concat("http://www.example.com/projects/" , acx_project_objects.project_id , "/tasks/" , acx_project_objects.integer_field_1) 'URL' 
FROM acx_comments, acx_project_objects 
LEFT JOIN acx_comments v ON v.parent_id = acx_project_objects.id 
WHERE acx_comments.id > 1500 AND acx_comments.id <= 1575 
GROUP BY acx_comments.id 
ORDER BY acx_comments.created_on DESC 
+0

這有效 - 但我選擇另一個作爲正確的答案,因爲它花費的處理能力要少得多。謝謝! – 2013-03-17 04:16:13