首页 > 解决方案 > 使用查询构建器优先考虑语言字段的教义左连接

问题描述

我正在使用以下查询:

use Doctrine\ORM\Query\Expr\Join;

$query = $this->createQueryBuilder('ad')
    ->select('ad.id, ad.title, ad.year, ad.hours, ad.status')
    ->addSelect('rem.remark')
    ->leftJoin('ad.remark', 'rem', Join::WITH, "rem.language = 'NL'")
    ->getQuery()
    ->getResult();

此查询运行良好,并返回荷兰语广告的备注。该广告与其评论具有一对多的关系。

只有我也有广告,例如有英文备注而不是荷兰语。I would like to get the English remark of that one and on others in the list. I would like to get the English remark of that one and on others in the list. I would like to get the English remark of that I would like to get the English remark 我希望得到我想要得到的我想要得到的那个列表中的其他人仍然是荷兰语的评论。所以也总结一下返回的语言的优先级列表?

标签: symfonyjoindoctrineleft-joinquery-builder

解决方案


解决此问题的一种方法是使用没有关系的额外连接:

$query = $this->createQueryBuilder('ad')
    ->select('ad.id, ad.title, ad.year, ad.hours, ad.status')
    ->addSelect('rem.remark')
    ->leftJoin('ad.remark', 'rem', Join::WITH, "rem.language = 'NL' OR rem.language = 'EN'")
    ->leftJoin(Remark::class, 'customRem', Join::WITH, 
    "rem.id <> customRem.id 
    AND rem.ad = customRem.ad 
    AND customRem.language = 'NL'")
    ->where('customRem.id IS NULL')
    ->getQuery()
    ->getResult();

这个想法是

  • 如果某个广告存在 NL 语言备注,则将此备注添加到该广告预期的每个结果行中(将为空)
  • 如果 NL 语言备注不存在且 EN 存在,则连接行将为空

最后,条件customRem.id IS NULL使这项工作。

多语言解决方案

在支持 3 种语言的情况下,因为DE > EN > NL,您可以这样做:

->leftJoin(Remark::class, 'customRem', Join::WITH,        
     "rem.id <> customRem.id AND rem.ad = 
      customRem.ad AND rem.language < customRem.language")

对于多种语言并假设具有“自定义”排序语言的能力,您可以使用:

"rem.id <> customRem.id 
AND rem.ad = customRem.ad AND 
(case when rem.language = 'NL' THEN 3 " .
"when rem.language = 'EN' THEN 2 " .
"when rem.language = 'DE' THEN 1 ELSE 0 END) < (case when customRem.language = 'NL' THEN 3 " .
"when customRem.language = 'EN' THEN 2 " .
"when customRem.language = 'DE' THEN 1 ELSE 0 END)"

或者,您可以创建“lang_position”表(id、语言、位置)并加入两次以从语言中获取位置。


推荐阅读