如果条件链接表中没有条目,则获取所有条目(Doctrine2,Symfony2)

时间:2015-10-26 11:59:04

标签: sql doctrine dql relation

有2个表:提供商和广告。提供商有广告。

第一张表"提供商":

  • ID
  • ...

第二张表"广告":

  • ID
  • 开始(日期时间)
  • 结束(日期时间)
  • ...

关联:

 /**
 * @ORM\OneToMany(targetEntity="Advert", mappedBy="provider", cascade={"persist"})
 */
private $adverts;

我想:

所有不提供任何当前有效广告的提供商(=目前介于"开始""结束")并且DON&T; T有任何广告计划在未来(="开始"和"结束"将来)。

换句话说:

我希望所有提供商不要有任何当前或即将推出的广告。

我的问题:

我不知道并找到任何有关如何操作的信息。

我使用Doctrine2和Symfony 2.8 / 3.0。

2 个答案:

答案 0 :(得分:1)

请注意,Doctrine默认不支持某些特定于MySQL的功能。您可以为此安装扩展程序。我将提出一种没有扩展的方法。 (但是你应该根据自己的判断选择一个Bundle

Provider存储库中,您可以执行以下操作:

public function getProvidersWithoutAdverts()
{
    $now = date("Y-m-d H:i:s");
    $qb = $this->createQueryBuilder('provider');

    $qb->leftJoin('provider.adverts', 'advert', Join::WITH)
       ->where("advert.end < {$now}") //Advert  has ended
       ->andWhere("advert.begin < {$now}") //Advert is not scheduled
       ;

    return $qb->getQuery()->getResult();

}

答案 1 :(得分:0)

此代码工作正常但可能尚未完全优化。

警告:您应该为Provider实体创建一个存储库。如果您有$em作为Doctrine EntityManager,则以下代码正常工作。

    $qb = $em->createQueryBuilder();
    $qb = $qb->select('IDENTITY(advert.provider)')
        ->from('AppBundle:Advert', 'advert')
        ->where("advert.begin <= :now AND advert.end > :now")
        ->andWhere('advert.active = true')
        ->setParameter(':now', new \DateTime(), Type::DATETIME)

    $nots = $qb->getQuery()->getArrayResult();

    $qb = $em->createQueryBuilder();
    $qb = $qb->select('p')
        ->from('AppBundle:Provider', 'provider')
        ->leftJoin('provider.adverts', 'advert');
    if (isset($nots[0])) {
        $qb->where($qb->expr()->notIn('provider.id', $nots[0]));
    }

    $providers = $qb->getQuery()->getArrayResult();

也许“不存在”会更好:NOT IN vs NOT EXISTS