2014-09-23 54 views
2

我有三個表:麻煩三重加入

訂單

orderID 
userID 

用戶

userID 
lastViewedOrderID 

votehistory

userID 
orderID 

我有一個PHP函數:getOrdersForUser($userID),它應該返回一組的orderID值與下列條件:

1)用戶還未觀看的訂單(orders.orderID> users.lastViewedOrderID)

2)的命令未被列入由用戶正在查詢(orders.userID!= users.userID)

3)尚未由用戶根據所述votehistory表表決(的orderID不在votehistory其中userID = [傳入的用戶ID值])

到目前爲止,我想出最好的是:

SELECT orders.orderID 
FROM orders 
JOIN users 
ON users.userID != orders.userID 
JOIN votehistory 
ON (votehistory.userID = users.userID) AND (votehistory.orderID != orders.orderID) 
WHERE users.userID = [the userID value passed in] 
AND orders.orderID > users.lastViewedOrderID 
AND likehistory.orderID != orders.orderID 

不幸的是,這給了我一噸重複 - 同樣的orderID重複在votehistory每個有效行。我似乎不瞭解JOIN過程如何優化。我應該嘗試減少通過子查詢連接的表中的行數?什麼是排除重複的最有效方法?

回答

0

增加了一些指標之後,我發現這個查詢的工作效率:

SELECT orders.orderID 
FROM orders 
WHERE orders.orderID NOT IN 
( 
    SELECT votehistory.orderID 
    FROM users 
    JOIN votehistory 
    ON (votehistory.userID = users.userID) 
    WHERE users.userID = [userID input value] 
) 
AND orders.userID != [userID input value] 
AND orders.orderID > 
(
    SELECT lastViewedOrderID 
    FROM users 
    WHERE userID = [userID input value] 
) 
ORDER BY orders.orderID ASC 
1

因爲你只想要orderID,你可以用EXISTS來做。就像這樣:

SELECT orders.orderID 
FROM orders 
WHERE EXISTS 
( 
    SELECT NULL 
    FROM users 
    JOIN votehistory 
    ON (votehistory.userID = users.userID) 
    WHERE users.userID != orders.userID 
    AND users.userID = [the userID value passed in] 
    AND (votehistory.orderID != orders.orderID) 
    AND orders.orderID > users.lastViewedOrderID 
    AND likehistory.orderID != orders.orderID 
) 

參考:

+0

這是一個好主意。實際上,我需要的不僅僅是orderID,這僅僅是我的表格的簡化版本。在這種情況下,我需要加入嗎? – GoldenJoe 2014-09-23 12:48:10

+0

@GoldenJoe:這取決於附加字段的來源。請記住,如果您進行加入可能會導致它再次返回重複項 – Arion 2014-09-23 13:21:35

+0

如果我想從三個表中的每一箇中獲得一個字段,該怎麼辦? – GoldenJoe 2014-09-23 19:44:26