首页 > 解决方案 > 如何使用查询构建器基于内部连接关系编写具有不同的自连接查询?

问题描述

我有一个实体Place可以容纳许多不同类型的地方,特别是在这种情况下是“城市”和“州”,其中每个“城市”都可以保存对指向父“州”的同一张表的引用。

我有另一个Office与 具有多对一关系的实体Place,但由于域限制,办公室只会链接到“城市”,而不会链接到“州”。

我必须编写一个查询来获取我们拥有一个或多个办事处的所有州,但仅限于那些。

在纯 SQL 中,查询很容易运行:

SELECT DISTINCT states.*
         FROM offices o
            INNER JOIN places cities ON cities.id = o.place_id
            INNER JOIN places states ON cities.parent_place_id = states.id
WHERE p.place_type = 'city'

这行得通,我们得到了我们需要的东西。

我需要(我更愿意)使用查询生成器编写查询。这是“基本”查询,但我们需要有条件地应用更多过滤器,这将使 QB 的使用更加清洁和易于管理。

目前我们使用的是Native Query,但这意味着我们需要在调用之前操作 SQL 字符串em::createNativeQuery(),这很麻烦。

$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('states')->distinct()
           ->from(PartnerOffice::class, 'o')
           ->innerJoin('o.place', 'p')
           ->innerJoin('p.parentPlace', 'states')
           ->where("p.placeType = 'city'");

但这给出了一个错误:

SELECT DISTINCT':错误:如果不选择至少一个根实体别名,则无法通过标识变量选择实体

我们怎样才能使这个查询工作?

谢谢并恭祝安康。

标签: phpsymfonydoctrine-ormdoctrinequery-builder

解决方案


在没有看到实体的情况下很难弄清楚应该构建的查询(至少对我而言)。例如:你有一个 mappedBy 字段吗?但我认为您的问题是您没有从 PartnerOffice 获取任何信息,而它是您的根条目(来自)。要么更改您的->select()for a ->addSelect,但这将获取每条记录的整个 PartnerOffice 实体,并且您的不同可能无法按预期工作,或者使用 Place 实体作为您的根条目并翻转逻辑。

假设您的实体的关系是双向的。应该这样做(但您可能需要为真实的实体和字段名称更改它)。

$this->getEntityManager()->createQueryBuilder()
    ->distinct()
    ->from(Place::class, 'p')
    ->join('p.cities', 'c')
    ->join(PartnerOffice::class, 'po', Join::WITH, 'po.place = p')
    ->andWhere('p.placeType = \'state\'');

推荐阅读