【问题标题】:Using complex calculated values with Eloquent在 Eloquent 中使用复杂的计算值
【发布时间】:2014-06-28 23:50:23
【问题描述】:

我有两张桌子、商店和地点。

现在我正在这样做:

$shops = Shop::with('location');
if (Input::has('location')) {
    $shops->whereHas('location', function($q) use ($input) {
        $q->where('name', '=', Input::get('location');
    });
}

return $shops->paginate(10);

一切顺利。

但是,我还想包含一个距离值,并按它排序。这基本上相当于创建一个计算值,我尝试这样做:

$shops->raw('(
    3959 * acos (
        cos ( radians(?) )
   * cos( radians( locations.lat ) )
   * cos( radians( locations.lon ) - radians(?) )
        + sin ( radians(?) )
   * sin( radians( locations.lat ) )
        )
) AS distance
', array(Session::get('latitude'), Session::get('longitude'), Session::get('latitude')));

(放在上面的返回值之前)

这没有任何作用 - 交换到 whereRaw 也不起作用。

我是否将不得不停止使用 Eloquent(再次!),或者这是 Eloquent 可以处理的问题?

【问题讨论】:

  • 2.您应该挂钩一个雄辩的事件并打印您的函数生成的实际 SQL - 然后您可以调试正在发生的事情。
  • 这就是全部代码了,我还没有具体定义raw函数。使用它时查询不会改变(可能是因为它不存在?)。使用 whereRaw 会引发异常。
  • 我在大声思考,因为您正在执行 计算函数 - 您可能需要在初次调用 Shop 时包含 raw()。所以也许像$shops = Show::with('location')->raw(<code>)
  • 似乎whereRaw 总是将代码放在SQL 中WHERE 语句之后,我想这是合乎逻辑的。之前不知道怎么写,我想如果可以的话,应该可以……
  • Cam 你只使用 raw()?另外 - 检查这个例子 - 你可以尝试 select() 与 DB::raw() - laravel.com/docs/queries#raw-expressions

标签: laravel laravel-4 eloquent


【解决方案1】:
  1. 您需要selectRaw 或select(DB::raw(...)),而不是whereRaw
  2. 您需要加入locations 表以从中进行选择(以在Shop 对象上附加距离)或将该部分放入加载Location 模型的查询中(以将距离附加到@ 987654327@对象):

    Shop::with(['location' => function ($q) {
       $q->selectRaw(' *, YOUR_CALC_HERE as distance'); 
       // don't forget to select all with '*'
    }]);
    

如果您想按距离订购商店,那么您肯定需要加入。

【讨论】:

    【解决方案2】:

    在 IRC 上得到一些帮助后,我决定这样做:

    // First, specify a manual join onto locations, so the values are available in this query
    $shops->join('locations', 'shops.location_id', '=', 'locations.id');
    
    // Second, add the selectRaw (which seems to not have variable binding?)
    $shops->selectRaw('(
        3959 * acos (
            cos ( radians('.Session::get('latitude').') )
    * cos( radians( locations.lat ) )
    * cos( radians( locations.lon ) - radians('.Session::get('longitude').') )
            + sin ( radians('.Session::get('latitude').') )
    * sin( radians( locations.lat ) )
            )
    ) AS distance
    ');
    
    // select the rest of the variables on shops afterwards to avoid any name collisons
    $shops->addSelect('shops.*');
    

    【讨论】:

      猜你喜欢
      • 2021-06-15
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 2020-07-26
      相关资源
      最近更新 更多