在多个表上进行条件 mysql 连接的最有效方法? (Yii php 框架)

Posted

技术标签:

【中文标题】在多个表上进行条件 mysql 连接的最有效方法? (Yii php 框架)【英文标题】:Most efficient way to do a conditional mysql join on multiple tables? (Yii php framework) 【发布时间】:2010-06-24 18:18:34 【问题描述】:

我有五张桌子:

    tab_template 模板组 群 用户组 用户

Tab_template 使用 template_group 关系表组织成组。 使用 user_group 关系表将用户组织成组。 组可以是公共的或私有的(使用表中的 tinyint 布尔列)。

我想查询所有的 tab_templates:

    与用户在同一组中 或在公共组中

这是我当前的查询:

tab_templatet中选择 * 左加入template_grouptemplate_group.tab_template_id=t.id 左加入grouptemplate_group.tab_template_id=group.id 左加入user_group 正确 在哪里group.private=0 或 (template_group.group_id=user_group.group_iduser_group.user_id=2) 分组t.id;

它可以工作,而且它本身并不是超级慢,但它是我加入 user_group 表的方式。

问题是我需要加入 user_group 表进行条件检查,但我只需要在组不是私有的情况下进行条件检查。

我知道我可以将另一个表添加到 FROM 子句(FROM tab_template tuser_group ug)中,而不是第三个 LEFT JOIN 条件...但我不能这样做是因为 Yii 的 ActiveRecord 类与 DcCriteria 一起使用的方式我无法修改语句的那部分。我可以编辑查询的任何其他部分,但不能编辑 FROM 子句。在此处查看 API:http://www.yiiframework.com/doc/api/CDbCriteria 这就是为什么我以我的方式加入 user_group 表的原因。一些 Yii 专家可能能够帮助我解决这个问题,但我不确定通过 FROMing 表而不是 JOINing 查询会更快。

任何帮助将不胜感激!谢谢

【问题讨论】:

【参考方案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

更易于阅读,更易于维护。

【讨论】:

这看起来很不错,但不幸的是我不能在 Yii 的 ActiveRecord 类中使用“UNION” @thaddeusmt:嘘。我将答案更改为社区 wiki,因此我可以将其作为示例【参考方案2】:

我这台机器上没有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
    )

【讨论】:

我也试过了,不幸的是,Yii 的 ActiveRecord 类在 JOIN 中的表别名存在问题。它会进行一些内部检查以确保表中存在这些列,并且它无法对所有内容进行排序。这个解决方案很有意义,而且非常易读,谢谢。

以上是关于在多个表上进行条件 mysql 连接的最有效方法? (Yii php 框架)的主要内容,如果未能解决你的问题,请参考以下文章

mysql中的连接查询

在 SSE2 上进行无符号 64 位比较的最有效方法是啥?

数据库(MYSQL)连接查询--sql92等值连接

lyt经典版MySQL基础——进阶6:连接查询-sql92语法-内连接

如何在同一张表上进行多个连接,然后与另一个表连接?

检查表中是不是存在行的最有效方法是啥?