首页 文章

Laravel - Eloquent或Fluent随机排

提问于
浏览
163

如何在Laravel框架中使用Eloquent或Fluent选择随机行?

我知道通过使用SQL,您可以通过RAND()进行排序 . 但是,我想让随机行 without 对初始查询之前的记录数进行计数 .

有任何想法吗?

11 回答

  • 8

    我有数千条记录的表,所以我需要快速的东西 . 这是伪随机行的代码:

    // count all rows with flag active = 1
    $count = MyModel::where('active', '=', '1')->count(); 
    
    // get random id
    $random_id = rand(1, $count - 1);  
    
    // get first record after random id
    $data = MyModel::where('active', '=', '1')->where('id', '>', $random_id)->take(1)->first();
    
  • 41

    Laravel> = 5.2:

    User::inRandomOrder()->get();
    

    Laravel 4.2.7 - 5.1:

    User::orderByRaw("RAND()")->get();
    

    Laravel 4.0 - 4.2.6:

    User::orderBy(DB::raw('RAND()'))->get();
    

    Laravel 3:

    User::order_by(DB::raw('RAND()'))->get();
    

    检查MySQL随机行上的 this article . Laravel 5.2支持这一点,对于旧版本,没有更好的解决方案,然后使用RAW Queries .

    edit 1: 正如Double Gras所提到的,自this更改以来,orderBy()不允许任何其他东西,然后是ASC或DESC . 我相应地更新了答案 .

    edit 2: Laravel 5.2最终为此实现a wrapper function . 它被称为 inRandomOrder() .

  • 1

    这很好用,

    $model=Model::all()->random(1);
    

    你也可以在随机函数中改变参数以获得多个记录 .

    注意:如果您有大量数据,则不推荐使用,因为这将首先获取所有行,然后返回随机值 .

  • 2

    tl;dr: 现在已经在Laravel中实现了,请参阅下面的"edit 3" .


    可悲的是,截至今天,提出的解决方案有一些注意事项:

    • 它不是DB不可知的 . 例如SQLite和PostgreSQL使用 RANDOM()

    • 更糟糕的是,此解决方案不再适用于this change

    $direction = strtolower($direction) == 'asc' ? 'asc' : 'desc';

    edit: 现在您可以使用orderByRaw()方法: ->orderByRaw('RAND()') . 然而,这仍然不是DB不可知的 .

    FWIW,CodeIgniter实现了一个特殊的 RANDOM 排序方向,在构建查询时将其替换为正确的语法 . 它似乎也很容易实现 . 看起来我们有改进Laravel的候选人:)

    更新:这是关于GitHub的issue,我的待定pull request .

    edit 2: 让我们切断追逐 . 从Laravel 5.1.18开始,您可以将宏添加到查询构建器:

    use Illuminate\Database\Query\Builder;
    
    Builder::macro('orderByRandom', function () {
    
        $randomFunctions = [
            'mysql'  => 'RAND()',
            'pgsql'  => 'RANDOM()',
            'sqlite' => 'RANDOM()',
            'sqlsrv' => 'NEWID()',
        ];
    
        $driver = $this->getConnection()->getDriverName();
    
        return $this->orderByRaw($randomFunctions[$driver]);
    });
    

    用法:

    User::where('active', 1)->orderByRandom()->limit(10)->get();
    
    DB::table('users')->where('active', 1)->orderByRandom()->limit(10)->get();
    

    edit 3: 终于来了!从Laravel 5.2.33(changelogPR #13642)开始,您可以使用本机方法 inRandomOrder()

    User::where('active', 1)->inRandomOrder()->limit(10)->get();
    
    DB::table('users')->where('active', 1)->inRandomOrder()->limit(10)->get();
    
  • 25

    在您的模型中添加:

    public function scopeRandomize($query, $limit = 3, $exclude = [])
    {
        $query = $query->whereRaw('RAND()<(SELECT ((?/COUNT(*))*10) FROM `products`)', [$limit])->orderByRaw('RAND()')->limit($limit);
        if (!empty($exclude)) {
            $query = $query->whereNotIn('id', $exclude);
        }
        return $query;
    }
    

    然后在路线/控制器

    $data = YourModel::randomize(8)->get();
    
  • 1

    您可以轻松使用此命令//问题:模型名称//从db获取10行在随机播放记录中...

    $ questions = Question :: orderByRaw('RAND()') - > take(10) - > get();

  • 9

    还有 whereRaw('RAND()') 也是如此,你可以链接 ->get()->first() 甚至疯狂添加 ->paginate(int)

  • 7

    Laravel 4 and 5order_byorderBy 取代

    所以,它应该是:

    User::orderBy(DB::raw('RAND()'))->get();
    
  • 406

    您可以使用:

    ModelName::inRandomOrder()->first();
    
  • 15

    对于Laravel 5.2> =

    使用Eloquent方法:

    inRandomOrder()
    

    inRandomOrder方法可用于随机对查询结果进行排序 . 例如,您可以使用此方法来获取随机用户:

    $randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();
    

    来自docs:https://laravel.com/docs/5.2/queries#ordering-grouping-limit-and-offset

  • 0

    您还可以使用具有流利和雄辩的order_by方法,如:

    Posts::where_status(1)->order_by(DB::raw(''),DB::raw('RAND()'));
    

    这有点奇怪的用法,但有效 .

    编辑:正如@Alex所说,这种用法更清晰,也有效:

    Posts::where_status(1)->order_by(DB::raw('RAND()'));
    

相关问题