首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用查询生成器编写基于内部连接关系的自联接查询?

如何使用查询生成器编写基于内部连接关系的自联接查询?
EN

Stack Overflow用户
提问于 2020-11-15 13:34:10
回答 2查看 667关注 0票数 0

我有一个实体Place,它可以容纳许多不同类型的地方,尤其是在“城市”和“国家”的情况下,每个“城市”都可以保存指向父“状态”的同一个表的引用。

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

我必须写一个查询,让所有的州,我们有一个或多个办事处,但只有那些。

在普通SQL中,查询工作非常简单:

代码语言:javascript
运行
复制
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,这很麻烦。

代码语言:javascript
运行
复制
$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:无法通过标识变量选择实体,而不选择至少一个根实体别名

我们如何使这个查询工作?

谢谢和问候。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-15 16:25:19

如果没有看到实体(至少对我来说),就很难理解应该构建的查询。你有mappedBy字段吗?但我认为您的问题是,您没有从PartnerOffice获取任何信息,而它是您的根条目(从)。要么将->select()更改为->addSelect,但这将为每个记录获取整个PartnerOffice实体,并且您的差异可能不像预期的那样工作,或者使用Place实体作为根条目并翻转逻辑。

让我们假设您的实体的关系是双向的。这样的东西应该可以完成(但是您可能需要将它更改为真实的实体和字段名)。

代码语言:javascript
运行
复制
$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\'');
票数 1
EN

Stack Overflow用户

发布于 2020-11-15 13:45:13

我认为您已经发布了一个不完整的基本sql查询(WHERE AND),并且您创建了一个别名p.place_type,这个别名在查询中没有定义。但是,从你的陈述中,我认为你可以尝试下面的查询,

代码语言:javascript
运行
复制
$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中的内部联接。

来源:

  1. https://laravel.com/docs/8.x/queries#inner-join-clause
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64845003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档