让我们假设我有实体User
和Comment
处于一对多关系。假设在模型中正确设置了关系,在User
模型中称为comments
。假设Comment
有一个字段text
,它是写在注解中的文本。
每个Comment
属于一个User
,但每个User
可以有任意数量的注解(包括根本没有注解)。
我用的是Doctrine-ORM 2.7我需要选择User
数据,如果存在,只选择他们最近评论的text
。我真的在努力拼凑如何做到这一点。到目前为止我的想法:
- 该查询应该使用用户ID上的
Comment
表leftJoin()
User
。我想我想要一个LEFT JOIN
,因为这样用户没有任何意见仍然被选中。 - Comments部分需要是一个嵌套查询,它对具有该用户ID的注解执行类似
ORDER BY id DESC LIMIT 1
的操作,以便只选择最近的一个。 - 我不认为我可以使用
groupBy()
,因为我需要选择最近评论的text
,但我可能会通过这里得到MAX(comment.id)
,这可能会派上用场?
目前为止,我的一次尝试进展如下:
$qb = $em->getRepository(User::class)
->createQueryBuilder('u')
->select('u.id, u.username') // ...etc. user data
->addSelect('c.text') // comment text
->leftJoin('u.comments', 'c', 'WITH', ....) // Place nested subquery here somehow?
->getQuery()
->getArrayResult();
我觉得嵌套查询应该是这样的:
$qb = $em->getRepository(Comment::class)
->createQueryBuilder('c')
->select('c.id')
->where('c.user', ':user')
->orderBy('id', 'desc')
->getQuery()
->getScalarResult();
这是一个虚构的例子;在真实的应用程序中,优化是一个关注点,因此我希望最小化执行的嵌套查询的数量。This answer似乎有一个很好的原始SQL方法,但我对如何将其转换为查询构建器语法感到困惑。如果你能帮忙的话,我将不胜感激。
1条答案
按热度按时间3qpi33ja1#
不知道我是否有你正在寻找的东西,但我想我只是面临着类似的问题。
下面是我提出的查询:
你仍然需要过滤最新的评论。
它为我的目的工作,虽然它给出了一个响应,看起来像这样:
而不是这样:
但那不是问题
编辑1:刚刚尝试使用它与一对多,它返回一个完整的用户对象的每一个评论。我还是要把锥子留在这里,可能会有点用。
编辑2:或者你可以使用DTO(数据传输对象)?或者这对你的需求来说太慢了?