2011-11-30 57 views
1

假设我有两张桌子。如何运行这个MySQL JOIN查询?

第一张表是角色列表。用户可以有很多人物角色。

mysql> select id, user_id, name from personas_personas; 
+----+---------+--------------+ 
| id | user_id | name   | 
+----+---------+--------------+ 
| 8 |  1 | startup  | 
| 9 |  1 | nerd   | 
| 10 |  1 | close  | 
| 12 |  2 | Nerd   | 
| 13 |  2 | Startup  | 
| 14 |  2 | Photographer | 
+----+---------+--------------+ 
6 rows in set (0.00 sec) 

现在,我有另一个名为“批准”的表。

mysql> select id, from_user_id, to_user_id, persona_id from friends_approvals; 
+----+--------------+------------+------------+ 
| id | from_user_id | to_user_id | persona_id | 
+----+--------------+------------+------------+ 
| 2 |   1 |   2 |   8 | 
| 3 |   1 |   2 |   9 | 
+----+--------------+------------+------------+ 
2 rows in set (0.00 sec) 

如果from_user要批准to_user一个角色,然后记录被插入。

我试图做到这一点查询...

给定用户,找到它的所有角色。然后,对于每个角色,确定它是否被批准用于某个to_user。如果是,请在结果集中返回is_approved = 1。否则,在结果集中返回is_approved = 0。

因此,这是我开始:

SELECT * 
FROM personas_personas 
WHERE user_id = 1 
LEFT JOIN friends_approvals ON 
...but i don't know where to go from here. 

所以,最终的结果集应该在personas_personas表中的所有列,然后也is_approved每个结果。

+0

仅供参考,你应该有一个用户,假面和UserPersona表(为了更好的标准化)。然后可能是一个拥有所有“批准”的UserPersonaUser表。 –

+0

@BradChristie我有一个用户表和一个角色表。为什么我需要UserPersona表? – TIMEX

+0

避免重复的人物角色。一旦角色“XYZ”是角色表,它不能被复制,只是简单地重新分配/使用。 UserPersonal将是一个多对多的关系。 (除非我错误地理解了这个方案 - 完全可能) –

回答

2
SELECT 
    pp.*, 
    CASE 
    WHEN exists (
     SELECT 
      * 
     FROM 
      friends_approvals fa 
     WHERE 
      fa.from_user_id = pp.user_id AND 
      fa.persona_id = pp.id AND 
      fa.to_user_id = 2 
     ) 
     THEN 1 
     ELSE 0 
    END as is_approved 

FROM 
    personas_personas pp 
WHERE 
    pp.user_id=1 

,或根据自己的口味:

SELECT 
    pp.*, 
    CASE 
    WHEN fa.from_user_id IS NOT NULL 
     THEN 1 
     ELSE 0 
    END as is_approved 

FROM 
    personas_personas pp 
    LEFT OUTER JOIN friends_approvals fa ON 
     pp.user_id = fa.from_user_id AND 
     pp.id = fa.persona_id AND 
     fa.to_user_id = 2 
WHERE 
    pp.user_id=1 
+1

这种一般方法可以工作,但是查询的一些细节对我来说并不合适。特别是,我不认为我们可以忽略'friends_approvals.persona_id'。 – ruakh

+0

嗨杰克,谢谢!起初这不起作用。但我添加了这个:“AND fa.persona_id = pp.id” – TIMEX

+0

是的,我刚刚更新了我的答案,包括在阅读@ ruakh的评论后 –

2

如果我正确理解你的需求,你可以这样做:

SELECT personas_personas.*, 
     CASE WHEN friends_approvals IS NULL THEN 0 ELSE 1 END AS is_approved 
    FROM personas_personas 
    LEFT 
OUTER 
    JOIN friends_approvals 
    ON friends_approvals.from_user_id = ... 
    AND friends_approvals.to_user_id = personas_personas.user_id 
    AND friends_approvals.persona_id = personas_personas.id 
WHERE personas_personas.user_id = ... 
; 

这会发现每个personas_personas记录与指定user_id以及该用户是否已通过指定from_user_id“批准”的指示符。

(如果这你想要的东西,那么请说明!)