Laravel 从查询生成器获取特定列
Posted
技术标签:
【中文标题】Laravel 从查询生成器获取特定列【英文标题】:Laravel get certain column from Query builder 【发布时间】:2016-11-07 07:28:42 【问题描述】:我有一个查询如下:
$locations = Location::select(DB::raw("* , 1000*distance AS distance"))
->whereIn("id", function ($q) use ($userLat, $distance, $userLng, $cityId)
$venues = $q->select('*')
->from('locations')
->where('city_id', $cityId)
->havingRaw("lat BETWEEN $userlat AND $userlat+10")
->havingRaw("lng BETWEEN $userLng AND $userlng+10")
->get();
)
->havingRaw('distance <' . $distance)
->orderBy('distance')
->take($limit)
->get();
我收到Cardinality violation
错误,我知道这是因为嵌套查询。
我只需要从嵌套查询中获取id
列,但我不能。
我曾尝试使用get(['id'])
,但没有成功。
我什至尝试使用array_map
并像array_map(function ($venue)return $venue->id, $venues);
一样返回某事,但我也遇到了同样的错误。
如何解决从查询生成器中仅获取 id
列作为数组。
我怎么能通过
【问题讨论】:
删除Location::select
并尝试仅使用 DB 外观。
【参考方案1】:
这只是一个猜测,但您的嵌套查询函数不应该由->get()
执行,并且您没有指定id
列。试试这个:
$locations = Location::select(DB::raw("* , 1000*distance AS distance"))
->whereIn("id", function ($q) use ($userLat, $distance, $userLng, $cityId)
$venues = $q->select('id')
->from('locations')
->where('city_id', $cityId)
->havingRaw("lat BETWEEN $userlat AND $userlat+10")
->havingRaw("lng BETWEEN $userLng AND $userlng+10")
;
)
->havingRaw('distance <' . $distance)
->orderBy('distance')
->take($limit)
->get();
编辑:使用查询范围和计算属性
$lat = ''; // latitude
$lng = ''; // longitude
$distance = 5; // distance amount
$radius = compact('lat', 'lng', 'distance');
$targets = Location::withinRadius($radius)
->with('city')
->get()
->map(function ($value, $key) use ($lat, $lng)
return $value->target = [$lat, $lng];
)
->filter(function ($value, $key) use ($distance)
return $value->distance < $distance;
)
;
app/Location.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Location extends Model
// Add the attributes for inclusion in toArray() and toJson()
protected $appends = ['target', 'distance'];
// Hold the target Location
protected $_target = null;
// ... other model code
/**
* Return the query with radius limits
*/
public function scopeWithinRadius($q, $radius)
$target_lat = $radius['lat'];
$target_lng = $radius['lng'];
$distance = $radius['distance'];
$target_lat_range = [$target_lat + $this->adjustLat($distance * -1), $target_lat + $this->adjustLat($distance)];
$target_lng_range = [$target_lng + $this->adjustLng($distance * -1), $target_lng + $this->adjustLng($distance)];
return $q->havingRaw("lat BETWEEN " . $target_lat_range[0] ." AND ".$target_lat_range[1])
->havingRaw("lng BETWEEN " . $target_lng_range[0] ." AND ".$target_lng_range[1])
;
/**
* Return the amount to adjust latitude by for the given distance
*/
private function adjustLat($distance)
// return latitude adjustment amount
/**
* Return the amount to adjust longitude by for the given distance
*/
private function adjustLng($distance)
// return longitude adjustment amount
/**
* Get the Target coordinates
*/
public function getTargetAttribute()
return $this->_target;
/**
* Get the Target latitude
*/
public function getTargetLatAttribute()
return $this->_target[0];
/**
* Get the Target longitude
*/
public function getTargetLngAttribute()
return $this->_target[1];
/**
* Set the Target of the Location
*/
public function setTargetAttribute($value)
// check if value is a Location
if ($value instanceof Location)
$value = [$value->lat, $value->lng];
$this->_target = $value;
/**
* Determine the Distance from target
*/
public function getDistanceAttribute()
$lat1 = $this->lat;
$lng1 = $this->lng;
$lat2 = $this->target_lat;
$lng2 = $this->target_lng;
// calculate the distance between Location and points
// ... $distance = ...
return $distance;
app/City.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class City extends Model
// ... other model code
/**
* Get the Location of the City
*/
public function location()
return $this->hasMany('App\Location');
【讨论】:
我在嵌套查询中使用lat
和 lng
,因此仅选择 id
将不起作用
在传统的 SQL 子查询中,除非您引用 lat
和 lng
列,否则您不需要选择它们。你在这里所做的一切都没有暗示。您从满足特定条件的记录中选择id
,不需要lat
和lng
。
distance
来自哪里?
距离是一个函数参数以上是关于Laravel 从查询生成器获取特定列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 laravel 查询生成器中为同一列构建多个条件的查询?
如何在执行查询之前从Laravel的查询生成器获取原始查询字符串?