如果链接 table 中没有符合条件的条目(Doctrine2、Symfony2),则获取所有条目
Get all entries if no entries in linked table with condition (Doctrine2, Symfony2)
有 2 个 table:提供商和广告。提供商有广告。
第一table"Provider":
- ID
- ...
第二个table"Advert":
- ID
- 开始(日期时间)
- 结束(日期时间)
- ...
关系:
/**
* @ORM\OneToMany(targetEntity="Advert", mappedBy="provider", cascade={"persist"})
*/
private $adverts;
我要:
所有当前没有任何广告的提供商(= 目前在 "Begin" 和 "End" 之间)并且没有任何计划在未来投放的广告(= "Begin"和"End"在未来)。
换句话说:
我想要所有没有任何当前或即将发布的广告的提供商。
我的问题:
我不知道如何做,也找不到任何信息。
我在 Symfony 2.8 / 3.0 中使用 Doctrine2。
请注意,某些 MySQL 特定功能在 Doctrine 中默认不支持。您可以为此安装一个扩展。我将提出一种无需扩展的方法。 (但您应该根据自己的判断选择退出捆绑包)
在您的 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();
}
此代码工作正常,但可能未完全优化。
警告:您应该为 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 exists" 会更好:NOT IN vs NOT EXISTS
有 2 个 table:提供商和广告。提供商有广告。
第一table"Provider":
- ID
- ...
第二个table"Advert":
- ID
- 开始(日期时间)
- 结束(日期时间)
- ...
关系:
/**
* @ORM\OneToMany(targetEntity="Advert", mappedBy="provider", cascade={"persist"})
*/
private $adverts;
我要:
所有当前没有任何广告的提供商(= 目前在 "Begin" 和 "End" 之间)并且没有任何计划在未来投放的广告(= "Begin"和"End"在未来)。
换句话说:
我想要所有没有任何当前或即将发布的广告的提供商。
我的问题:
我不知道如何做,也找不到任何信息。
我在 Symfony 2.8 / 3.0 中使用 Doctrine2。
请注意,某些 MySQL 特定功能在 Doctrine 中默认不支持。您可以为此安装一个扩展。我将提出一种无需扩展的方法。 (但您应该根据自己的判断选择退出捆绑包)
在您的 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();
}
此代码工作正常,但可能未完全优化。
警告:您应该为 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 exists" 会更好:NOT IN vs NOT EXISTS