仅连接符合特定条件的行(左连接的数据)

时间:2014-01-07 14:44:58

标签: sql join doctrine-orm left-join

我的用户拥有与其关联的FacebookPage和应用程序实体。 FacebookPage实体也有与之关联的应用程序实体。

    $qb = $this->createQueryBuilder('u')
        ->addSelect('p', 'a')
        ->leftJoin('u.facebook_pages', 'p')
        ->leftJoin('p.applications', 'a')
        ->leftJoin('a.editors', 'e', 'WITH', 'e = :user')
        ->where('u = :user')
        ->setParameter('user', $user)
        ->orderBy('p.name', $order)
        ;

    $u = $qb->getQuery()->getSingleResult();

    return $u->getFacebookPages();

我想返回所有用户的Facebook页面,然后显示与该页面关联的应用程序计数。我只想计算用户是编辑器的应用程序。

当我运行当前查询时,页面会计算所有页面的应用程序(因此计数包括用户不是编辑者的应用程序)。

如果我将a.editors leftJoin更改为join,我会获得正确的网页计数,但它只列出实际拥有任何应用程序的网页。

如何显示所有页面并仅加入用户为编辑器的应用程序?

1 个答案:

答案 0 :(得分:0)

我通过添加新查询来解决这个问题,以获取用户是编辑器的应用程序的应用ID。

    $user_apps = $this->getEntityManager()->getRepository('Application')->getUserApps($user);
    $app_ids = array();
    foreach($user_apps as $app) {
        $app_ids[] = $app->getId();
    }

    $qb = $this->createQueryBuilder('u')
        ->addSelect('p', 'a')
        ->leftJoin('u.facebook_pages', 'p');

    if(count($app_ids)) {
        // join with IN statement to include only apps where user is an editor
        $qb->leftJoin('p.applications', 'a', 'WITH', sprintf('a.id IN (%s)', implode(',', $app_ids)));
    } else {
        // join empty anyway to avoid db calls when iterating over pages
        $qb->leftJoin('p.applications', 'a');
    }

    $qb
        ->where('u = :user')
        ->setParameter('user', $user)
        ->orderBy('p.name', $order)
        ;

    try {
        $u = $qb->getQuery()->getSingleResult();
    } catch (Exception $e) {
        throw $e;
    }

    return $u->getFacebookPages();

现在返回所有用户的Facebook页面,并且只加入用户是编辑器的应用程序。我可能会将此更改为DQL查询,因此我可以将IN中的ID移动到子查询。