雄辩的haversine公式没有按预期工作
Posted
技术标签:
【中文标题】雄辩的haversine公式没有按预期工作【英文标题】:Eloquent haversine formula is not working as expected 【发布时间】:2019-08-23 16:09:25 【问题描述】:我陷入了半正弦公式,在我的情况下它仍然不起作用。
在以下示例中,我获取了用户及其所有关系。我需要根据与搜索地址的距离来检索用户。按照下面的说明,我收到以下错误:未找到列:1054 Unknown column 'distance' in 'having clause'
“activity_latitude”和“activity_longitude”都存储在我开始获取数据的主用户表中。我做错了什么?
$q = self->whereNull("deleted_at")->where("group_id", 1)
->with([
"data",
"rating",
"pendingcontents",
"openinghours",
"openinghours.dayofweek",
"openinghoursexceptions",
"isopeningtime",
"contents",
"contents.translation",
]);
$q->selectRaw('( 3959 * acos( cos( radians(?) ) *
cos( radians( activity_latitude ) )
* cos( radians( activity_longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( activity_latitude ) ) )
) AS distance', [$geocodedAddress[0], $geocodedAddress[1], $geocodedAddress[0]])
->havingRaw("distance < ?", [$radius]);
那么我还需要按距离订购。
总结一下,我只需要根据距离取值,按距离排序即可。
我不明白为什么这个版本有效...使用相关表格及其坐标
$q->whereHas('businessdata', function ($q) use ($filtro, $geocodedAddress, $radius)
$q->selectRaw('( 3959 * acos( cos( radians(?) ) *
cos( radians( activity_latitude ) )
* cos( radians( activity_longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( activity_latitude ) ) )
) AS distance', [$geocodedAddress[0], $geocodedAddress[1], $geocodedAddress[0]])
->havingRaw("distance < ?", [$radius]);
);
【问题讨论】:
@thmsdnnr 虽然works in mysql @thmsdnnr 我想检查需要 2 秒 :-( 如果是我,我会创建一个存储过程来计算距离,然后调用它两次——一次在 SELECT 子句中,一次在 WHERE 子句中。这似乎违反直觉,但我怀疑这比在 HAVING 子句中调用别名要快。如果性能很关键,那么您还可以考虑创建一个边界框,但这将在别处讨论。 确实...感谢您的更正! (删除上面关于 MySQL 不允许在 HAVING 子句中使用别名的错误评论,如 MS SQL)。 @thmsdnnr 随意删除误导性的 cmets。 【参考方案1】:为您分配了一个别名(距离)。
您可以简单地使用来自
的orderBy()
https://laravel.com/docs/5.8/queries#ordering-grouping-limit-and-offset
这将允许您使用距离别名。即
$q->selectRaw('( 3959 * acos( cos( radians(?) ) *
cos( radians( activity_latitude ) )
* cos( radians( activity_longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( activity_latitude ) ) )
) AS distance', [$geocodedAddress[0], $geocodedAddress[1], $geocodedAddress[0]])
->havingRaw("distance < ?", [$radius])
->orderBy("distance");
您还可以为方向传递第二个可选参数(默认为'asc')。
【讨论】:
但是之前还有一个问题需要解决:column not found: 1054 Unknown column 'distance' in 'have Clause' - 似乎距离别名不存在或被解释为列名.我需要的只是按距离和按距离排序 尝试将havingRaw() 换成where。 have 用于过滤组,而 where 用于过滤行。从您的查询来看,您似乎在过滤之前没有对任何内容进行分组? 我用了 where 但还是同样的问题...距离不存在以上是关于雄辩的haversine公式没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式
Rails expect(controller).not_to have_received(:get_from_database) 没有按预期工作