2010-04-25 59 views
1

我似乎记得在某处读到了将LEFT JOIN语句组合成更简单的查询的方法。我有以下查询,并希望有人可以好好看看它。在mysql中结合连接的语法

SET @userId = 8; 

SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches 
FROM user_goal ug, user u, profile p 
LEFT JOIN user_block ub ON @userId = ub.blocked_id 
LEFT JOIN user_block ub2 ON @userId = ub2.blocker_id 
LEFT JOIN user_user uu ON @userId = uu.user_id 
LEFT JOIN friend_request fr ON @userId = fr.user_id 
WHERE ug.user_id = u.id AND u.profile_id = p.id 
AND (ub.blocker_id IS NULL OR ub.blocker_id != ug.user_id) 
AND (ub2.blocked_id IS NULL OR ub2.blocked_id != ug.user_id) 
AND (uu.user_friends_id IS NULL OR uu.user_friends_id != ug.user_id) 
AND (fr.to_user_id IS NULL OR (fr.to_user_id != ug.user_id)) 
AND [email protected] 
AND p.suggestible 
AND goal_id IN (SELECT iug.goal_id FROM user_goal iug WHERE [email protected]) 
GROUP BY user_id ORDER BY matches DESC LIMIT 4 

回答

3

您可以通过删除@userId与开始提高这一总体查询;)你可以只是参考前面提到的列来维护加盟。

这可能会导致您的子查询出现问题;这并不需要在那里。该子查询几乎肯定会导致查询执行速度缓慢。您可以将子查询合并到您也加入的派生表中(因为它使用相同的user_id),这样它只执行一次,而不是像现在发生的那样对结果集中的每个记录执行一次。

SELECT 
    ug.user_id, 
    COUNT(DISTINCT goal_id) as matches 
FROM 
    user_goal ug 
    INNER JOIN user u ON ug.user_id = u.id 
    INNER JOIN profile p ON u.profile_id = p.id 
    LEFT JOIN user_block ub ON u.id = ub.blocked_id 
    LEFT JOIN user_block ub2 ON u.id = ub2.blocker_id 
    LEFT JOIN user_user uu ON u.id = uu.user_id 
    LEFT JOIN friend_request fr ON u.id = fr.user_id 
    LEFT JOIN (
    SELECT iug.goal_id FROM user_goal 
) iug ON iug.user_id = u.id 
WHERE 
    /* I looked at your WHERE clause for a while and couldn't get my head 
    around what you're trying to do so I'll leave this to you */ 

把子查询直接进入JOIN和命名它创建一个派生表,真的加速东西(和整理东西恕我直言)