我想知道用户根据其创建日期的位置。我如何使用Eloquent做到这一点?
我希望能够做到这样的事情:
User::getRowNumber($user_obj);
答案 0 :(得分:9)
我想你想要MySQL解决方案,所以你可以这样做:
DB::statement(DB::raw('set @row:=0'));
User::selectRaw('*, @row:=@row+1 as row')->get();
// returns all users with ordinal 'row'
所以你可以实现这样的东西:
public function scopeWithRowNumber($query, $column = 'created_at', $order = 'asc')
{
DB::statement(DB::raw('set @row=0'));
$sub = static::selectRaw('*, @row:=@row+1 as row')
->orderBy($column, $order)->toSql();
$query->remember(1)->from(DB::raw("({$sub}) as sub"));
}
public function getRowNumber($column = 'created_at', $order = 'asc')
{
$order = ($order == 'asc') ? 'asc' : 'desc';
$key = "userRow.{$this->id}.{$column}.{$order}";
if (Cache::get($key)) return Cache::get($key);
$row = $this->withRowNumber($column, $order)
->where($column, '<=',$this->$column)
->whereId($this->id)->pluck('row');
Cache::put($key, $row);
return $row;
}
这需要从表中选择所有行,直到找到您要查找的行,然后仅选择该特定行号。
它可以让你这样做:
$user = User::find(15);
$user->getRowNumber(); // as default ordered by created_at ascending
$user->getRowNumber('username'); // check order for another column
$user->getRowNumber('updated_at', 'desc'); // different combination of column and order
// and utilizing the scope:
User::withRowNumber()->take(20)->get(); // returns collection with additional property 'row' for each user
由于此范围要求每次将原始语句设置@row
设置为0,因此我们使用缓存1分钟以避免不必要的查询。
答案 1 :(得分:2)
$query = \DB::table(\DB::raw('Products, (SELECT @row := 0) r'));
$query = $query->select(
\DB::raw('@row := @row + 1 AS SrNo'),
'ProductID',
'ProductName',
'Description',
\DB::raw('IFNULL(ProductImage,"") AS ProductImage')
);
// where clauses
if(...){
$query = $query->where('ProductID', ...));
}
// orderby clauses
// ...
// $query = $query->orderBy('..','DESC');
// count clause
$TotalRecordCount = $query->count();
$results = $query
->take(...)
->skip(...)
->get();
答案 2 :(得分:0)
我相信您可以使用Raw Expresssions来实现这一目标:
$users = DB::table('users')
->select(DB::raw('ROW_NUMBER() OVER(ORDER BY ID DESC) AS Row, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
然而,通过source code看起来在使用SQLServer和offset时可以达到相同的效果。消息来源表明,如果你喜欢以下内容:
$users = DB::table('users')->skip(10)->take(5)->get();
生成的SQL查询将包含 row_number over 语句。
答案 3 :(得分:0)
[对于Postgres]
在您的模型中
public function scopeWithRowNumber($query, $column = 'id', $order = 'asc'){
$sub = static::selectRaw('*, row_number() OVER () as row_number')
->orderBy($column, $order)
->toSql();
$query->from(DB::raw("({$sub}) as sub"));
}
在您的控制器中
$user = User::withRowNumber()->get();