CakePHP 2.x中SELECT的快速子查询

yeotifhr  于 12个月前  发布在  PHP
关注(0)|答案(1)|浏览(154)

尽可能地抽象,我想执行:

select id,complicatedCalculation as geodistance from User join others having geodistance < 100;

在CakePHP 2.x中。实际的查询使用聚合,所以我们确实需要 having。当数据库是MySQL时,这一切都可以工作,因为该数据库在 having 子句中接受列引用。我们现在转向Postgres,它更严格地实现了SQL标准,并报告geodistance不存在。
SQL中的解决方案是将指令编写为

select * from (select id, complicatedCalculation as geodistance from User join others) as sub where geodistance < 100;

但是我不知道如何在Cake中表达这个子查询。目前为止我最好的尝试是

$db = $this->User->getDataSource();
$core = [ 'fields' => [ 'id', 'complicatedCalculation as geodistance' ],
        'table' => $db->fullTableName($this->User),
        'join' => (others) ]
$sub_query = $db->buildStatement($core, $this->User);
$result = $this->User->find('all', [
        'fields' => [ 'id', 'geodistance' ],
        'table' => $db->expression($sub_query),
        'alias' => 'zzz',  // not used but PGSQL requires it.
        'conditions' => [ 'geodistance <=' => 100 ]
    ]);

但这会在日志中生成以下SQL(抽象)报告为错误:

SELECT "User"."id" AS "User__id", complicatedCalculation as geodistance FROM "public"."users" AS "User" LEFT JOIN (others) WHERE "geodistance" <= 100

所以我尝试让CakePHP使用表达式作为表是不起作用的。我能让它这么做吗?
建议升级到当前版本的Cake的答案是不可接受的。如果没有其他方法,我们就使用query()

5w9g7ksd

5w9g7ksd1#

两个都不好。他们可能会被完全相同的处决。让我们看看EXPLAIN SELECT ...
真实的问题是必须为每一行计算geodistance,而且没有简单的方法来加快速度。
这里有5种方法
你的第一次,是最大的一次。Find Nearest
最好使用SPATIAL索引。这将需要改变数据存储的方式。
另一个不错的方法是建立一个“边界框”,然后有两个索引。
这两种选择都将在该链接中讨论。
您的查询是“在100内查找全部”。链接谈到“在100内找到最接近的N”。

相关问题