Laravel: How to get last N entries from DB

前端 未结 7 844
太阳男子
太阳男子 2021-02-01 01:07

I have table of dogs in my DB and I want to retrieve N latest added dogs.

Only way that I found is something like this:

Do         


        
相关标签:
7条回答
  • 2021-02-01 01:09

    The Alpha's solution is very elegant, however sometimes you need to re-sort (ascending order) the results in the database using SQL (to avoid in-memory sorting at the collection level), and an SQL subquery is a good way to achieve this.

    It would be nice if Laravel was smart enough to recognise we want to create a subquery if we use the following ideal code...

    $dogs = Dogs::orderByDesc('id')->take(5)->orderBy('id')->get();
    

    ...but this gets compiled to a single SQL query with conflicting ORDER BY clauses instead of the subquery that is required in this situation.

    Creating a subquery in Laravel is unfortunately not simply as easy as the following pseudo-code that would be really nice to use...

    $dogs = DB::subQuery( 
        Dogs::orderByDesc('id')->take(5) 
    )->orderBy('id');
    

    ...but the same result can be achieved using the following code:

    $dogs = DB::table('id')->select('*')->fromSub(
        Dogs::orderByDesc('id')->take(5)->toBase(), 
        'sq'
    )->orderBy('id');
    

    This generates the required SELECT * FROM (...) AS sq ... sql subquery construct, and the code is reasonably clean in terms of readability.)

    Take particular note of the use of the ->toBase() function - which is required because fromSub() doesn't like to work with Eloquent model Eloquent\Builder instances, but seems to require a Query\Builder instance). (See: https://github.com/laravel/framework/issues/35631)

    I hope this helps someone else, since I just spent a couple of hours researching how to achieve this myself. (I had a complex SQL query builder expression that needed to be limited to the last few rows in certain situations).

    0 讨论(0)
  • 2021-02-01 01:13

    You can pass a negative integer n to take the last n elements.

    Dogs::all()->take(-5)
    

    This is good because you don't use orderBy which is bad when you have a big table.

    0 讨论(0)
  • 2021-02-01 01:13

    Ive come up with a solution that helps me achieve the same result using the array_slice() method. In my code I did array_slice( PickupResults::where('playerID', $this->getPlayerID())->get()->toArray(), -5 ); with -5 I wanted the last 5 results of the query.

    0 讨论(0)
  • 2021-02-01 01:15
    Dogs::orderBy('created_at','desc')->take(5)->get();
    
    0 讨论(0)
  • 2021-02-01 01:19

    You may try something like this:

    $dogs = Dogs::orderBy('id', 'desc')->take(5)->get();
    

    Use orderBy with Descending order and take the first n numbers of records.

    0 讨论(0)
  • 2021-02-01 01:31

    My solution for cleanliness is:

    Dogs::latest()->take(5)->get();
    

    It's the same as other answers, just with using built-in methods to handle common practices.

    0 讨论(0)
提交回复
热议问题