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