Select 个假设相关实体不存在的实体

Select entities assuming related entity does not exist

我的实体(产品)与另一个名为 deletedByCompanies.

的实体(公司)有单向多对多关系

我希望 select 所有未被特定公司删除的产品。这是所有未通过多对多关系连接的产品。

尝试过:

$this->em->getRepository(Product::class)->createQueryBuilder('t')
->leftJoin('t.deletedByCompanies', 'deletedCompany')
->andWhere('deletedCompany.id not in (:companyId)')
->setParameter('companyId', [$companyId]);

但这根本没有 return 任何东西。 架构非常简单:

Product:
   id: int PK

Company:
   id: int PK

DeletedProducts
   product_id: int FK
   company_id: int FK

产品中的实体定义 class:

/**
 * @var Company[]
 * @ORM\ManyToMany(targetEntity="Company", indexBy="id")
 * @ORM\JoinTable(name="DeletedProducts")
 */
protected $deletedByCompanies;

我对 Doctrine 不熟悉,但我正在尝试提供一些 SQL 知识方面的帮助。以下查询应该做你想做的:

SELECT DISTINCT Product.* FROM Product
LEFT JOIN DeletedProducts on product_id = product.id
WHERE product_id IS NULL OR product_id !=
    ALL( SELECT product_id FROM DeletedProducts WHERE company_id = 2 )

一些解释...

DISTINCT: Nessacary 关键字以防止冗余。相同的产品如果被 删除,可能会在 Left Join 的结果中出现多次。 DISTINCT 消除那些重复项。

WHERE product_id IS NULL: Left Join 也会列出与以上任何公司无关的产品"DeletedProducts"-table。由于没有关系,字段 product_idcompany_idNULL .

OR product_id != ALL( [...] ): 现在我们已经得到了没有被任何公司删除的产品,我们需要另外还有那些没有被特定公司删除的。因此,我们将 OR 与子查询一起使用,该子查询选择某个公司的所有已删除产品(例如代码示例中的公司 id = 2)。因为我们想要未删除的产品,所以我们必须使用“!=”-Operator。

希望对您有所帮助。现在由您"translate"查询 Doctrine 中的用法。

我认为您可以通过删除 table 上的 NOT EXISTS 子句来解决您的问题。

在SQL方言中:

SELECT * FROM product p WHERE NOT EXISTS
 (SELECT * FROM DeletedProducts d WHERE p.id=d.product_id AND company_id = 2 );

在 Doctrine2 DQL 中,我们没有实体 DeletedProducts 所以我们必须做更多的事情,比如:

$qb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('t')
    ->Join('t.deletedByCompanies', 'deletedCompany')
    ->andWhere('deletedCompany.id  in (:companyId)')
    ->andWhere("p=t");

$mainQb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('p');
$mainQb->where($mainQb->expr()->not($mainQb->expr()->exists($qb->getDQL())));
$mainQb->setParameter('companyId', [$companyId]);

var_dump($mainQb->getQuery()->getSql());
$res =$mainQb->getQuery()->execute();

如果我不明白你的问题,请告诉我。

希望对您有所帮助