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_id 和 company_id 是 NULL .
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();
如果我不明白你的问题,请告诉我。
希望对您有所帮助
我的实体(产品)与另一个名为 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_id 和 company_id 是 NULL .
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();
如果我不明白你的问题,请告诉我。
希望对您有所帮助