在多个表上加入有条件的MySQL的最有效方法? (YII PHP框架)
-
29-09-2019 - |
题
我有五个桌子:
- tab_template
- Template_group
- 团体
- user_group
- 用户
TAB_Template与Template_Group关系表分为组。用户与User_group关系表分为组。小组可以是公共或私人的(使用表中的Tinyint布尔列)。
我想查询所有要么的tab_templates:
- 在与用户同一组中
- 或在公共团体中
这是我当前的查询:
选择 * tab_template
t
左加入 template_group
在 template_group
.tab_template_id
=t
.id
左加入 group
在 template_group
.tab_template_id
=group
.id
左加入 user_group
真实
在哪里
group
.private
=0
或者
(template_group
.group_id
=user_group
.group_id
和
user_group
.user_id
=2)
通过...分组 t
.id
;
它有效,而且本身并不是超级慢,但是我加入User_group表的方式是骇人听闻的。
问题是我需要加入User_group表以进行有条件的检查,但是我只需要进行条件检查,如果组不是私有的。
我知道,而不是左第三连接,而是与“真实”状态加入,我可以在从子句中添加另一个表(从 tab_template
t
, user_group
ug
)...但是我不能这样做,因为Yii的ActivereCord类的方式与dccriteria一起工作,我无法修改该陈述的一部分。我几乎可以编辑查询的其他任何部分,而不是从子句中编辑。在此处查看API: http://www.yiiframework.com/doc/api/cdbcriteria 这就是为什么我以自己的方式加入User_group表的原因。一些YII专家可能能够帮助我解决这个问题,但是我不确定从桌子上而不是加入它们而不是加入它们,我的查询会更快。
任何帮助将不胜感激!谢谢
解决方案
我对这种情况的建议是使用工会:
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
易于阅读的方式,使其更容易维护。
其他提示
我在这台计算机上没有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
)