按协会过滤学说实体

时间:2017-10-27 11:45:03

标签: php doctrine-orm doctrine

我有一个名为Company的实体。关联映射如下:

manyToOne:
    headCompany:
        targetEntity: CompanyEntity
        inversedBy: headCompany
oneToMany:
    subsidiaries:
        targetEntity: CompanyEntity
        mappedBy: headCompany

一切正常。公司可以是另一家公司的子公司和/或拥有自己的子公司。

现在,我需要过滤其他公司或拥有子公司的公司。

我可以直接用SQL做到这一点:

SELECT c.id, COUNT(s.headCompany_id) subsidiaries FROM companies c LEFT JOIN companies s ON s.headCompany_id = c.id GROUP BY c.id HAVING subsidiaries > 0

导致这样的事情:

+----+--------------+
| id | subsidiaries |
+----+--------------+
| 1  | 3            |
+----+--------------+
| 5  | 2            |
+----+--------------+

然后,公司1和5适合我的过滤器,因为他们都有子公司。

如何使用Doctrine Query Builder实现相同的结果?

我的尝试是:

$query = $qb->select('e')
    ->from('CompanyEntity', 'e')
    ->orderBy('e.id', 'ASC')
    ->join('e.headCompany', 'h')
    ->addSelect("COUNT(h.id) as subsidiaries")
    ->groupBy("e.id")
    ->having("subsidiaries > 0");

这个回归子公司,而非主要公司。

->where($qb->expr()->isNotNull("e.subsidiaries"))

显然,Doctrine不允许这样做。

2 个答案:

答案 0 :(得分:0)

如何反转加入条款,选择公司并加入子公司,然后对与每家公司相关的子公司数量应用过滤器

$query = $qb->select('h,s')
    ->from('CompanyEntity', 'h')
    ->join('h.subsidiaries', 's')
    ->addSelect("COUNT(s.id) AS HIDDEN subsidiaries")
    ->groupBy("h.id")
    ->orderBy('h.id', 'ASC')
    ->having("subsidiaries > 0");
  

当您使用sqlmode =>only_full_group_by时,除非它们存在于分组依据中,否则您无法选择实体的所有列,因此必须在select()中选择要返回的列。

$query = $qb->select('h.id')
    ->from('CompanyEntity', 'h')
    ->join('h.subsidiaries', 's')
    ->addSelect("COUNT(s.id) AS HIDDEN subsidiaries")
    ->groupBy("h.id")
    ->orderBy('h.id', 'ASC')
    ->having("subsidiaries > 0");
  

根据官方文档“ONLY_FULL_GROUP_BY拒绝查询,其中选择列表,HAVING条件或ORDER BY列表引用既未在GROUP BY子句中命名也未在功能上依赖于(唯一确定)GROUP BY列的非聚合列。“

答案 1 :(得分:0)

您应该能够逐个使用订单,有点像这样:

$query = $qb->select('e')
    ->from('CompanyEntity', 'e')
    ->join('e.headCompany', 'h')
    ->addSelect("(CASE WHEN COUNT(h.id) > 0 THEN 1 ELSE 0 END) as sort_sub")
    ->groupBy("e.id")
    ->orderBy("sort_sub");

您可以在此主题中详细了解它:How to ORDER BY CASE in Doctrine2 (Symfony2)