我有一个实体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 的更加干净和易于管理。
目前我们使用的是本机查询,但这意味着在调用em::createNativeQuery()之前需要操作string,这很麻烦。
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('states')->distinct()
->from(PartnerOffice::class, 'o')
->innerJoin('o.place', 'p')
->innerJoin('p.parentPlace', 'states')
->where("p.placeType = 'city'");但这给出了一个错误:
选择DISTINCT':Error:无法通过标识变量选择实体,而不选择至少一个根实体别名
我们如何使这个查询工作?
谢谢和问候。
发布于 2020-11-15 16:25:19
如果没有看到实体(至少对我来说),就很难理解应该构建的查询。你有mappedBy字段吗?但我认为您的问题是,您没有从PartnerOffice获取任何信息,而它是您的根条目(从)。要么将->select()更改为->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\'');发布于 2020-11-15 13:45:13
我认为您已经发布了一个不完整的基本sql查询(WHERE AND),并且您创建了一个别名p.place_type,这个别名在查询中没有定义。但是,从你的陈述中,我认为你可以尝试下面的查询,
$qb->selectRaw('DISTINCT s.states')
->from('offices as o')
->join('places as c', 'c.id', '=', 'o.place_id')
->join('places as s', 's.id', '=', 'c.parent_place_id')
->where('c.placeType', 'city')->get();默认情况下,->join()引用queryBuilder中的内部联接。
来源:
https://stackoverflow.com/questions/64845003
复制相似问题