三联接有问题

时间:2014-09-23 06:00:06

标签: mysql join

我有三张桌子:

订单

orderID
userID

用户

userID
lastViewedOrderID

votehistory

userID
orderID

我有一个PHP函数:getOrdersForUser($userID),它应该返回一组具有以下条件的orderID值:

1)用户尚未查看订单(orders.orderID> users.lastViewedOrderID)

2)被查询的用户没有下订单(orders.userID!= users.userID)

3)该用户未根据投票历史表投票(orderID不在投票历史中,其中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。我似乎不明白JOIN过程是如何优化的。我是否应该尝试减少通过子查询加入的表中的行数?排除重复项的最有效方法是什么?

2 个答案:

答案 0 :(得分: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
)

参考:

答案 1 :(得分: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