按多列排序 - Doctrine查询构建器

4

我想在多个列上使用orderBY语句,但是它们应该像一个单独的列一样起作用。表格看起来像这样:

col1 | col2
5    |
2    |
     | 3
7    |
     | 1
     | 1

结果应该看起来像这样:
col1 | col2
     | 1
     | 1
2    |
     | 3
5    |
7    |

如果我们使用原始SQL,会有像使用COALESCE这样的方法。
但是在Doctrine QueryBuilder中如何实现呢?
编辑:
我尝试像这样使用orderBy:
qb->orderBy("COALESCE(col1, col2)", "DESC");

And like this

qb->add("orderBy", "COALESCE(col1, col2) DESC");

但两次都遇到了以下错误:

[Syntax Error] line 0, col 700: Error: Expected end of string, got '(' 

1
作为一个好的解决方案 - 创建自定义Doctrine函数来实现COALESCE方法。 - ZhukV
2
你尝试过使用coalesce吗?它已经包含在语言语法中了。 - Krzysztof
@Lolo,感谢您的评论。我已经编辑了我的问题。也许我用错了吗? - Robin
@ZhukV 抱歉,但我可能不太熟悉Doctrine的使用。你有关于它的更多文档/信息吗? - Robin
1
似乎是不可能的:https://dev59.com/kWMl5IYBdhLWcg3wwZPc - Stephan Vierkant
@StephanVierkant 谢谢,我之前看过这篇帖子,但他们并没有找到解决方案。我想也许我们可以找到其他的东西。我也不一定要使用 coalesce,这只是我的解决方案而已。 - Robin
1个回答

5
尝试在select语句中添加order列,然后按照该列排序。
$qb = $em->createQueryBuilder();
$qb
    ->select('entity', 'COALESCE(col1, col2) as orderCol')
    ->from('Namespace/Entity', 'entity')
    ->orderBy('orderCol', 'DESC')

也许使用beberlei/DoctrineExtensions库中的IF可以有所帮助。使用composer安装它(或者如果你愿意,你也可以只复制一个文件),并将函数注册到config.yml中。
doctrine:
    orm:
      entity_managers:
        default:
          dql:
            string_functions:
              IF: DoctrineExtensions\Query\Mysql\IfElse 

并构建查询

$qb = $em->createQueryBuilder();
$qb
    ->select('entity', 'IF(col1, col1, col2) as orderCol')
    ->from('Namespace/Entity', 'entity')
    ->orderBy('orderCol', 'DESC')

另一个选择是使用 Native Query 以纯 MySQL 的方式并将结果映射到实体。

谢谢您的回复。我明天会测试这个并给您反馈。但我真的不想使用原始的mysql查询。您知道什么更有效吗?IF还是COALESCE? - Robin
8
我可以确认 @forgottenbas 的解决方案可行,因为我几天前也遇到了类似的情况。另外,我建议加上 HIDDEN 关键字,以保持结果集结构的干净整洁,但这并不是必须的:COALESCE(col1, col2) as HIDDEN orderCol - Jovan Perovic
@Robin 不知道哪个更快,通常不是查询中最慢的部分,但在这个问题中有一些信息。 - Alexey B.
@Jovan Perovic:感谢您的帮助!如果您在Symfony 2.8中将其用作EntityType字段的“query_builder”参数,则此项是必需的! - Thomas Landauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接