Cake PHP 连接查询以关联数组形式返回

Posted

技术标签:

【中文标题】Cake PHP 连接查询以关联数组形式返回【英文标题】:Cake PHP joined query returned as associative array 【发布时间】:2013-09-13 09:38:05 【问题描述】:

好的,这是我的表/模型结构:模型已适当关联。

我正在尝试查询给定客户 ID 的 持有价值总和,并将给定价值总和的日期作为数组键。

我查阅了文档,我在客户端模型中为我的查询生成了以下参数:

$findParameters = array(
    'conditions' => array(
        'Account.client_id' => $clientId,
        'Holding.holding_date = LAST_DAY(Holding.holding_date)', //gets month-end dates only
        'MONTH(Holding.holding_date)' => array(3,6,9,12) //Use for quarter-end dates
        ),
    'fields' => array(
        'Holding.holding_date',
        'SUM(Holding.value) AS portfolio_value'
        ),
    'group' => array('Holding.holding_date')
);

当我运行查询时

$holdings = $this->Account->Holding->find( 'all', $findParameters );

我得到这样的结果:

Array
(
    [0] => Array
        (
            [Holding] => Array
                (
                    [holding_date] => 2009-12-31
                )

            [0] => Array
                (
                    [portfolio_value] => 273239.07
                )

        )

    [1] => Array
        (
            [Holding] => Array
                (
                    [holding_date] => 2010-03-31
                )

            [0] => Array
                (
                    [portfolio_value] => 276625.28
                )

        )
...

这很好,但我想要这样的数组中的结果:

Array (
    [2009-12-31] => 273239.07
    [2010-03-31] => 276625.28
    ...
)

所以我尝试这样做:

$holdings = $this->Account->Holding->find( 'list', $findParameters )

但我得到了错误:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Account.client_id' in 'where clause'

查询看起来好像不再对表执行连接。知道为什么,如果我使用all 而不是list 效果很好?以及如何获得我想要的结果?


编辑:我已经使用 Cake 的 hash 类实现了我的结果,但我想知道直接查询是否是一种更优越、更有效的方法。

我的方法:

    $holdings = $this->Account->Holding->find( 'all', $findParameters );

    $values = Hash::extract($result, 'n.0.portfolio_value');
    $dates = Hash::extract($result, 'n.Holding.holding_date');

    $result = array_combine($dates, $values);
    return $result;

【问题讨论】:

哈哈,我也用哈希技巧完成了我的回答。很好,你自己找到了 ;) -edit:实际上,我以不同的方式做,但 Hash::combine 正在做你所做的事情:2 次提取和一次合并。 【参考方案1】:

一般评论

Cakephp 的 ORM 非常适合轻松查找查询(包括 group by sort...)。当涉及到更高级的东西时,您需要处理在 PHP 中检索到的数据或制作plain SQL Query。

关于关联数组

Model::find('all')Model::find('first') 将始终返回关联数组。其他 find 方法将返回不同类型的数组,但您将无法使用开箱即用的模型函数获得所需的结果。

关于未添加到正确子数组的字段

当您拥有SUM()AVG()COUNT() 时,要让您的字段正确显示在一起,您可以阅读此处about virtual fields in SQL Queries

如何在 CakePHP 中提取/格式化数组

最简单的方法是使用Hash 类以您想要的方式提取和格式化数据。

使用Hash::combine,您可以像这样实现您想要的:

$result = Hash::combine($holdings, 'n.Holding.holding_date', 'n.0.portfolio_value');

【讨论】:

不幸的是,当我使用 AS Holding.portfolio_value 时出现 SQLSTATE 错误 虽然你的方法没有第一步确实有效,而且 1-liner 比 3-liner 要好! @harryg 我添加了一个指向文档的链接,您可以在其中看到执行我在第一步中尝试的正确方法。 有帮助,但不能在条件下使用。你的方法虽然没有但效果很好,我相信它非常有效!【参考方案2】:

请尝试

$findParameters = array(
    'conditions' => array(
        'Account.client_id' => $clientId,
        'Holding.holding_date = LAST_DAY(Holding.holding_date)', //gets month-end dates only
        'MONTH(Holding.holding_date)' => array(3,6,9,12) //Use for quarter-end dates
        ),
    'fields' => array(
        'Holding.holding_date',
        'SUM(Holding.value) AS portfolio_value'
        ),
    'group' => array('Holding.holding_date'),
    'contain' => array('Account),
);

【讨论】:

不幸的是,这没什么区别

以上是关于Cake PHP 连接查询以关联数组形式返回的主要内容,如果未能解决你的问题,请参考以下文章

存储过程与数组连接查询

Cake php 4 使用数组中的关联保存数据

php中实现数据关联查询的原理是怎样的?

数据库连接查询,如果a表关键b,b表关键c。a能关联c进行查询吗?

带有连接的休眠自定义 SQL 查询 - 避免返回数组列表

PHP 数据库连接