2010-06-24 70 views
1

我有五個表:在多個表上執行條件mysql連接的最有效方法? (Yii的PHP框架)

  1. tab_template
  2. template_group
  3. USER_GROUP
  4. 用戶

Tab_template的組織成與template_group關係組表。 用戶與user_group關係表組成用戶組。 羣組可以是公共或私人的(在表格中使用tinyint布爾列)。

我想查詢所有要麼是tab_templates的:

  1. 在同一個組的用戶
  2. 或在公共組

這裏是我當前的查詢:

SELECT * FROM tab_templatet
LEFT JOIN template_group
ON template_grouptab_template_id = tid
LEFT JOIN group
ON template_grouptab_template_id = groupid
LEFT JOIN user_group
ON TRUE
WHERE
groupprivate = 0
OR
template_groupgroup_id = user_groupgroup_id
AND
user_groupuser_id = 2)
GROUP BY tid;

它的工作原理,它本身並不是超慢的,但是我加入user_group表的方式很不方便。

問題是,我需要加入user_group表進行條件檢查,但我只需要做這種條件檢查,如果該組不是私人的。

我知道的,而不是第三LEFT JOIN即與真條件我可以FROM子句中的另一個表添加到(FROM tab_templatetuser_groupug)...但我不能這樣做,因爲這樣的Yii的ActiveRecord類與DcCriteria一起使用我無法修改該語句的這一部分。我可以編輯查詢的任何其他部分,但不能編輯FROM子句。看看這裏的API:http://www.yiiframework.com/doc/api/CDbCriteria所以這就是爲什麼我加入user_group表的方式。Yii的一些專家或許能夠幫助我解決這個問題,但是我不確定我的查詢會從表中刪除而不是加入它們,從而加快查詢速度。

任何幫助將不勝感激!由於

回答

1

我像這些情況的建議是使用UNION:

SELECT t.* 
    FROM TAB_TEMPLATE t 
    JOIN TEMPLATE_GROUP tg ON tg.tab_template_id = t.id 
    JOIN GROUP g ON g.id = tg.tab_template_id 
       AND g.private = 0 
UNION 
SELECT t.* 
    FROM TAB_TEMPLATE t 
    JOIN TEMPLATE_GROUP tg ON tg.tab_template_id = t.id 
    JOIN GROUP g ON g.id = tg.tab_template_id 
       AND g.private != 0 
    JOIN USER_GROUP ug ON ug.group_id = g.id 

路更容易閱讀,這使得它更容易維護。

+0

這看起來很不錯,但不幸的是我不能使用Yii的ActiveRecord類的「UNION」 – thaddeusmt 2010-06-25 18:58:42

+0

@thaddeusmt:Boooooo。我改變了社區wiki的答案,所以我可以把它作爲一個例子 – 2010-06-25 19:04:21

0

我沒有MySQL的這臺機器上,所以我不能對此進行測試:

SELECT 
    TT.col1, 
    TT.col2, 
    ... 
FROM 
    Tab_Templates TT 
WHERE 
    EXISTS 
    (
     SELECT * 
     FROM 
      Template_Groups TG 
     WHERE 
      TG.tab_template_id = TT.id AND 
      TG.private = 0 
    ) OR 
    EXISTS 
    (
     SELECT * 
     FROM 
      User_Groups UG 
     INNER JOIN Template_Groups TG2 ON 
      TG2.tab_template_id = TT.id AND 
      TG2.group_id = UG.group_id 
     WHERE 
      UG.user_id = 2 
    ) 
+0

我剛剛嘗試過這一點,不幸的是Yii的ActiveRecord類在JOIN中的表別名存在問題。它會進行一些內部檢查以確保列中存在列,並且它無法將所有內容排序。這個解決方案很有意義,而且非常可讀,謝謝。 – thaddeusmt 2010-06-25 19:02:26

相關問題