【问题标题】:Calculate coordinate distance in Laravel在 Laravel 中计算坐标距离
【发布时间】:2017-11-01 18:32:36
【问题描述】:

我的模型中有一个范围,它创建了一个别名,我需要在其上执行一个 where,我知道 MySql 不允许这样做。

标准 SQL 不允许您在 WHERE 中引用列别名 条款。施加此限制是因为当 WHERE 代码位于 执行,列值可能尚未确定。

但是,我想知道是否有可能的 laravel 解决方法? 我的示波器创建了一个别名距离,我想检查距离。

public static function scopeDistance($query, $lat, $long)
{
    return $query->select(array('*',\DB::raw('( 3959 * acos( cos( radians(' . $lat . ') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(' . $long . ') ) + sin( radians(' . $lat .') ) * sin( radians(latitude) ) ) ) AS distance')));
} 

在我的控制器中:

\App\Profile::distance($latitude, $longitude)->where('distance', '<', 50);

【问题讨论】:

    标签: php mysql laravel laravel-5 eloquent


    【解决方案1】:

    首先,不要忘记从函数调用中删除 static 关键字,Laravel 处理神奇的静态外观 Profile::distance 调用。

    以下是解决同一问题的 2 个不同选项,无论哪种情况,您都会从控制器调用 \App\Profile::distance($latitude, $longitude, 50)

    选项 1

    您可以在内存中进行计算,而不是处理子查询。

    public function scopeDistance($query, $lat, $long, $distance) {
        return Profile::all()->filter(function ($profile) use ($lat, $long, $distance) {
            $actual = 3959 * acos(
                cos(deg2rad($lat)) * cos(deg2rad($profile->latitude))
                * cos(deg2rad($profile->longitude) - deg2rad($long))
                + sin(deg2rad($lat)) * sin(deg2rad($profile->latitude))
            );
            return $distance < $actual;
        });
    }
    

    选项 2

    您可以执行 SQL 子查询,请确保以 get() 结束调用:

    public function scopeDistance($query, $lat, $long, $distance) {
        return $query->having('distance', '<', $distance)
                 ->select(DB::raw("*,
                         (3959 * ACOS(COS(RADIANS($lat))
                               * COS(RADIANS(latitude))
                               * COS(RADIANS($long) - RADIANS(longitude))
                               + SIN(RADIANS($lat))
                               * SIN(RADIANS(latitude)))) AS distance")
                 )->orderBy('distance', 'asc')
                  ->get();
    }
    

    【讨论】:

    • 很好的答案!我想知道如何更改此范围以实际将距离作为配置文件表上的新列返回?
    猜你喜欢
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多