【问题标题】:symfony2 multiple left join, inner joinsymfony2 多重左连接,内连接
【发布时间】:2013-03-29 00:13:49
【问题描述】:

使用 symfony2 但它更多只是 mysql 问题...

我认为我有很好的表架构(只是重要的字段)(代码是不言自明的):

用户(ID) 状态(id) 喜欢(id,user_id,status_id) cmets (id,user_id,status_id)

我正在做大选择。

正在尝试这个:

    $qb=$this->createQueryBuilder('s')
             ->addSelect('u')
             ->addSelect('u2')
             ->addSelect('u3')
             ->addSelect('l')
             ->addSelect('c')
             ->addSelect('s2')
             ->where('s.user = :user')
             ->setParameter('user', $user)
             ->innerJoin('s.user', 'u')
             ->leftJoin('s.likes', 'l')
             ->leftJoin('l.user', 'u2')
             ->leftJoin('s.comments', 'c')
             ->leftJoin('c.user', 'u3')
             ->leftJoin('c.status', 's2')
             ->orderBy('s.time', 'DESC')
             ->setMaxResults(15);

但结果是 15 个相同的状态...错误。

当我只选择状态时效果很好......喜欢状态......和用户(喜欢和状态的作者)

这样:

SELECT * FROM statuses s0_ 
INNER JOIN users t1_ ON s0_.user_id = t1_.id 
LEFT JOIN status_likes s2_ ON s0_.id = s2_.status_id
INNER JOIN users t3_ ON s2_.user_id = t3_.id  

WHERE s0_.user_id = 25 ORDER BY s0_.time DESC LIMIT 15

效果很好,但是我如何实现另一个 cmets 和(用户 -> cmets 的作者)选择那里?...

【问题讨论】:

    标签: symfony join doctrine-orm left-join inner-join


    【解决方案1】:

    您无法以您尝试的方式在连接查询上设置最大结果。

    您需要使用此处描述的分页器: http://docs.doctrine-project.org/en/latest/tutorials/pagination.html

    如果它在您的 Doctrine 版本中不可用(您是 2.2 之前的版本),那么您可以在此处使用分页器: https://github.com/beberlei/DoctrineExtensions

    另一种选择是不在查询中执行连接 - 而是简单地允许自动获取连接的数据。因此,遍历用户并遍历对象图以获取您需要的信息。这显然会发出更多的查询:

    $users = $userRepository->findById($user);
    $i = 0;
    for ($users as $user){
        $likes = $user->getLikes(); 
        $comments = $user->getComments();
        $i++;
        if ($i == 15) { break; }
    }
    

    编辑:将“继续”更改为“中断”;无论如何,这都是糟糕的代码 - 不要使用它,我只是在说明一个替代方案。

    最后,您可以使用本机查询来执行此操作:

    http://docs.doctrine-project.org/en/2.1/reference/native-sql.html

    编辑:类似问题:Limiting a doctrine query with a fetch-joined collection?

    【讨论】:

    • 第一次听说分页...我认为我是 2.2.3.. 我需要用尽可能少的查询和最好的性能来做到这一点...我有我的查询自己的存储库,当我查看您的分页链接时……我很困惑发生了什么……(凌晨 2 点)您能否向我展示我的情况更友好的示例,几乎没有解释,否则工作量太大?顺便说一句:当我从查询 THE LIMIT 语句中删除时,我得到所有状态......但是每个状态都返回了大约 30 次???好像写得不太好……还是?
    • 您是否尝试过分页文档顶部的代码?我怀疑您可能正在尝试像 SQL 一样使用 DQL,但这不是一回事。在示例中,您可以通过像这样从查询构建器中提取查询来获取相同的对象 $query。 $qb->getQuery();按照示例将其输入分页器,看看是否有帮助。
    • 谢谢!嗯,分页似乎正在工作。但是当我尝试 count($paginator) 时,我看到:50。这是什么意思? + 当我在 phpmyadmin 中尝试 SQL 时,你对这么多相同的返回行怎么说? (首先来自评论的问题)。像状态ID这样的信息...现在我通过 $status->getId() 访问并且没有 $status['id'] (我之前在查询中有 getArrayResult )...但是没关系似乎正在工作我只是不知道现在的表现??从 13 毫秒我有 260 毫秒!第一个查询选择不同的状态 ID。其次是从这些 id 中选择所有数据。嗯???
    • @Trki 这就是分页的工作原理。由于由于 fetch-joined 结果而无法信任结果的数量,因此您首先需要选择根实体的标识符(不同的),然后使用 IN() 子句仅匹配第二个结果中的子集。
    • 嗯...但是有这么多查询?如此多的时间??我认为250毫秒很多..不是吗?所有查询都只是 2ms 或类似的.. 现在这个?嗯……这是最好的吗?我的选择写得好吗?请仔细检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多