如何得到一个一维标量数组作为一个学说dql查询结果?

Posted

技术标签:

【中文标题】如何得到一个一维标量数组作为一个学说dql查询结果?【英文标题】:How to get a one-dimensional scalar array as a doctrine dql query result? 【发布时间】:2012-07-24 08:42:46 【问题描述】:

我想从 Auction 表的 id 列中获取一组值。 如果这是一个原始 SQL,我会写:

SELECT id FROM auction

但是当我在 Doctrine 中执行此操作并执行时:

$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); 

我得到一个这样的数组:

array(
    array('id' => 1),
    array('id' => 2),
)

相反,我想得到一个这样的数组:

array(
    1,
    2
)

我怎样才能使用 Doctrine 做到这一点?

【问题讨论】:

【参考方案1】:

由于 doctrine/orm 2.10.0 有一个内置的解决方案,请参阅https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/dql-doctrine-query-language.html#scalar-column-hydration

use Doctrine\ORM\AbstractQuery;

$query = $em->createQuery("SELECT a.id FROM Auction a");
return $query->getSingleColumnResult();
// Same as:
return $query->getResult(AbstractQuery::HYDRATE_SCALAR_COLUMN);

【讨论】:

【参考方案2】:

php

您可以使用array_map,并且由于每个数组只有一个项目,因此您可以优雅地使用 'current' 作为回调,而不是写一个closure。

$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_map('current', $result);

有关内存使用的更多信息,请参阅Petr Sobotka's answer below。

PHP >= 5.5

作为jcbwlkr's answered below,推荐使用array_column

【讨论】:

getScalarResult() 会给你字符串 - 如果你想要整数,请使用 getArrayResult() 所以! array_column() 在内存管理方面更好还是 foreach 方式,我们应该怎么做?【参考方案3】:

更好的解决方案是使用 PDO:FETCH_COLUMN 。为此,您需要一个定制的保湿器:

//MyProject/Hydrators/ColumnHydrator.php
namespace DoctrineExtensions\Hydrators\mysql;

use Doctrine\ORM\Internal\Hydration\AbstractHydrator, PDO;

class ColumnHydrator extends AbstractHydrator

    protected function hydrateAllData()
    
        return $this->_stmt->fetchAll(PDO::FETCH_COLUMN);
    

将其添加到 Doctrine:

$em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');

你可以这样使用它:

$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");

更多信息: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes

【讨论】:

我已经修改了这个,所以它支持 indexBy gist.github.com/ostrolucky/f9f1e0b271357573fde55b7a2ba91a32【参考方案4】:

从 PHP 5.5 开始,您可以使用array_column 来解决这个问题

$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_column($result, "id");

【讨论】:

【参考方案5】:

Ascarius 的回答很优雅,但要注意内存使用! array_map() 创建传递数组的副本并有效地使内存使用量翻倍。如果您使用数十万个数组项,这可能会成为一个问题。由于 PHP 5.4 调用时按引用传递已被删除,所以你不能这样做

// note the ampersand
$ids = array_map('current', &$result);

在这种情况下,你可以选择明显的

$ids = array();
foreach($result as $item) 
  $ids[] = $item['id'];

【讨论】:

这似乎有点违反直觉,因为我们的目标是在这两种情况下“几乎复制”数组。我必须亲自测试它才能确信它是真的:gist.github.com/PowerKiKi/9571aea8fa8d6160955f【参考方案6】:

我认为这在 Doctrine 中是不可能的。 只需使用 PHP 将结果数组转换为您想要的数据结构:

$transform = function($item) 
    return $item['id'];
;
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());

【讨论】:

以上是关于如何得到一个一维标量数组作为一个学说dql查询结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除学说 Doctrine Raw Sql 查询中的特定 dql 部分?

与学说 dql 连接的子查询

为啥我不能绘制不是标量、一维或 (2, n) 数组的东西?

用于标量查询的 Doctrine 返回数组数组

如何在学说 2 中创建对象属性的查询构建器

DQL 和等效 SQL 不返回相同数量的结果集