2011-03-17 38 views
1

我現在有兩個表的用戶,其中的「阻塞」字段中的值將是1,0,或NULL:如何篩選與連接表

用戶

ID,

等....

聯繫

user_id_1

user_id_2

受阻

*其中user_id_1是以下用戶,並user_id_2是跟隨用戶(在Twitter上的模型)我目前正在修改我的內部*


消息系統允許所有用戶向所有其他用戶發送消息,唯一的限制是如果用戶A消息用戶B,但用戶B已經阻止了用戶A,消息將不會通過。

考慮到這一點,看看這個查詢:

SELECT u.id, IFNULL(c.blocked, 0) AS blocked 
FROM cms_users u 
    LEFT JOIN cms_connections c ON u.id=c.user_id_2 AND c.user_id_1=71 
WHERE u.id IN (62, 65, 89, 90) 

這裏的想法是,用戶71正試圖郵件用戶62,65,89和90用戶71是繼62, 65,和89,但不繼90.然而,用戶89已經阻止用戶71.這意味着有一些像這樣的連接表項:

user_id_1  user_id_2  blocked 
71    62    0 
71    65    0 
71    89    1 

當我運行此查詢,我得到這個結果:

user_id_1  blocked 
62    0 
65    0 
89    1 
90    0 

這正是我所期望的,但如果我改變WHERE子句是這樣的:

WHERE u.id IN (62, 65, 89, 90) AND blocked=0 

然後我得到這個:

user_id_1  blocked 
62    0 
65    0 

這是令人困惑的我,因爲我米期待三行:上面兩個和用戶90的一個。我也試着做一個GROUP BYHAVING blocked!=1HAVING blocked=0,他們都產生相同的結果。我也嘗試將創建的列的名稱更改爲blockherpderp,以檢查與我的JOIN是否有衝突,但產生了相同的結果。

好奇地想看看你們能想出:-)

回答

3

更改爲IFNULL(c.blocked, 0)

SELECT u.id, 
     Ifnull(c.blocked, 0) AS blocked 
FROM cms_users u 
     LEFT JOIN cms_connections c 
     ON u.id = c.user_id_2 
      AND c.user_id_1 = 71 
WHERE u.id IN (62, 65, 89, 90) 
     AND Ifnull(c.blocked, 0) = 0 

如果改寫成

SELECT u.id, 
     Ifnull(c.blocked, 0) AS blocked 
FROM cms_users u 
     LEFT JOIN cms_connections c 
     ON c.user_id_1 = 71 
      AND u.id = c.user_id_2 
     JOIN (SELECT 62 AS uu 
      UNION ALL 
      SELECT 65 AS uu 
      UNION ALL 
      SELECT 89 AS uu 
      UNION ALL 
      SELECT 90 AS uu) d 
     ON u.id = d.uu 
WHERE Ifnull(c.blocked, 0) = 0 

你需要索引的查詢這可以提高

  • (cms_users.id)
  • (cms_connections.user_id_1,cms_connections.user_id_2,cms_connections.user_id_2.blocked)
+0

真棒...這工作!謝謝! – treeface 2011-03-17 21:23:34

1

嘗試:HAVING IFNULL(c.blocked,0)= 0