Chọn hàng cuối cùng trong bảng


163

Tôi muốn lấy lại tập tin cuối cùng được chèn vào bảng của tôi. Tôi biết rằng phương thức này first()tồn tại và cung cấp cho bạn tệp đầu tiên trong bảng nhưng tôi không biết làm thế nào để có được lần chèn cuối cùng.


Ngoài ra, hãy xem stackoverflow.com/questions/33321447/ Từ Cách sắp xếp một mối quan hệ hiện có (hasMany)
Tarek Adam

Điều này là cho bất cứ ai hỏi và trả lời về Laravel. Hãy nhớ rằng điều quan trọng là chỉ định phiên bản Laravel mà bạn đang nói đến. Nói chung phiên bản 4 và 5 có sự khác biệt và phiên bản cũ hơn.
Heroselohim

Câu trả lời:


223

Bây giờ bạn sẽ cần phải đặt hàng theo cùng một lĩnh vực mà bạn đang đặt hàng, nhưng giảm dần. Ví dụ: nếu bạn có dấu thời gian khi tải lên được gọi xong upload_time, bạn sẽ làm một cái gì đó như thế này;

Dành cho Pre-Laravel 4

return DB::table('files')->order_by('upload_time', 'desc')->first();

Dành cho Laravel 4 trở đi

return DB::table('files')->orderBy('upload_time', 'desc')->first();

Dành cho Laravel 5.7 trở đi

return DB::table('files')->latest('upload_time')->first();

Điều này sẽ sắp xếp các hàng trong bảng tệp theo thời gian tải lên, thứ tự giảm dần và lấy cái đầu tiên. Đây sẽ là tập tin tải lên mới nhất.


15
Đối với Laravel 4, điều này nên orderBy, không phảiorder_by
Jared Eitnier

9
Khi bạn sử dụng ORM, đây là một cách chính xác:User::orderby('created_at', 'desc')->first();
Cas Bloem

1
Ấu trùng 5.x =orderBy('created_at', 'desc')
0x1ad2

9
Tại sao bạn sử dụng cột created_at? Nhanh hơn nhiều để sử dụng ID khóa chính. Laravel 5.x Files::orderBy(id', 'desc')->first();Sắp xếp theo ngày hoạt động lâu hơn vì ngày là chuỗi và rất có thể không được lập chỉ mục. Trong khi khóa chính được lập chỉ mục và hoạt động siêu nhanh. Ngay cả khi created_at được lập chỉ mục, nó là chuỗi được lập chỉ mục và không phải INT trong trường hợp chính. Chuỗi chỉ số có hiệu suất ít hơn.
KorbenDallas

4
Nhận xét @KorbenDallas nên là câu trả lời vì đôi khi orderBy('created_at', 'desc')không cung cấp cho bạn hàng cuối cùng. Ví dụ: 3 hàng có thể có chính xác cùng một giá trị TIMESTAMP và với orderBy('created_at', 'desc')bạn sẽ nhận được hàng đầu tiên trong số 3 (không nhất thiết là hàng cuối cùng)
viery365

111

Sử dụng phạm vi mới nhất được cung cấp bởi Laravel ra khỏi hộp.

Model::latest()->first();

Bằng cách đó, bạn không lấy được tất cả các hồ sơ. Một phím tắt đẹp hơn để orderBy.


7
Lưu ý rằng phương pháp này sử dụng created_atcột được tạo tự động ($timestamps = true)trong Mô hình, nhưng có thể bị vô hiệu hóa theo ý muốn nên bạn sẽ gặp lỗi nếu không xác định
Plotis Nghiệp dư

Tôi đang sử dụng Laravel 5.7 và cố gắng thực hiện điều này trên Model vẫn lấy tất cả các bản ghi cho tôi.
CJ Dennis

1
Lưu ý rằng nếu bạn có nhiều bản ghi được thêm trong cùng một giây, thời gian created_at sẽ giống nhau cho các bản ghi này và do đó bản ghi được trả về bởi mới nhất () có thể không phải là bản ghi mà bạn mong đợi.
F3CP

Lưu ý rằng bạn không cần cột 'created_at'. Bạn có thể chỉ định từ cột nào bạn muốn mới nhất. Ví dụ: Model :: mới nhất ('dateColumn') -> first ();
Tom

Điều này có thể không nhận được hàng cuối cùng thực tế nếu hai hàng được chèn trong vòng 1 giây (thực sự gây ra sự cố trong kiểm tra đơn vị).
ớt

75

Bạn chưa bao giờ đề cập đến việc bạn có đang sử dụng Eloquent, ORM mặc định của Laravel hay không. Trong trường hợp bạn là, giả sử bạn muốn nhận mục nhập mới nhất của bảng Người dùng, bằng created_at, bạn có thể làm như sau:

User::orderBy('created_at', 'desc')->first();

Đầu tiên, nó ra lệnh cho người dùng theo trường created_at, giảm dần và sau đó nó lấy bản ghi đầu tiên của kết quả.

Điều đó sẽ trả về cho bạn một thể hiện của đối tượng Người dùng, không phải là một bộ sưu tập. Tất nhiên, để sử dụng thay thế này, bạn phải có một mô hình Người dùng, mở rộng lớp Eloquent. Điều này nghe có vẻ hơi khó hiểu, nhưng thực sự dễ dàng để bắt đầu và ORM có thể thực sự hữu ích.

Để biết thêm thông tin, hãy xem tài liệu chính thức khá phong phú và chi tiết.


42

Để có được thông tin chi tiết cuối cùng

  1. Model::all()->last(); hoặc là
  2. Model::orderBy('id', 'desc')->first();

Để có được bản ghi cuối cùng

  1. Model::all()->last()->id; hoặc là
  2. Model::orderBy('id', 'desc')->first()->id;

14

Bộ sưu tập Laravel có phương pháp cuối cùng

Model::all() -> last(); // last element 
Model::all() -> last() -> pluck('name'); // extract value from name field. 

Đây là cách tốt nhất để làm điều đó.


16
Chỉ muốn chỉ ra rằng all()phương thức thực sự tải tất cả các mục. Điều này sẽ không hoạt động trên một bảng với hàng triệu hồ sơ.
Steven Jeffries

1
Ngoài nhận xét của Steven Jeffries, tôi muốn chỉ ra rằng việc gọi last()trả về một thể hiện Eloquent duy nhất chứ không phải là Bộ sưu tập và gọi pluck()đó là bằng cách gọi Model::all()->pluck('name'), do đó trả về namethuộc tính của tất cả các hàng trong bảng
ivcandela

5
Phương pháp này thực sự tồi tệ hơn. Bạn đang tìm nạp phần thô cuối cùng bằng cách sử dụng thực thi PHP thay vì thực hiện dưới dạng mức DB. Điều gì sẽ xảy ra nếu bảng có hàng triệu nguyên liệu, sau đó bạn có biết nó có thể kém hiệu quả đến mức nào không?
Bhaskar Dabhi

Đây là cách tốt nhất để làm điều đó. - Không! Chưa bao giờ, sẽ không bao giờ. Bạn sẽ tải tất cả các hàng thay vì chỉ một hàng bạn cần.
René Roth

11

Thử cái này :

Model::latest()->get();

1
Điều này sẽ trả về nhiều hàng. Anh ta cần một hàng duy nhất. first () sẽ giúp anh ta với mệnh đề orderBy ().
Tahir Afridi

Điều này có thể không nhận được hàng cuối cùng thực tế nếu hai hàng được chèn trong vòng 1 giây (thực sự gây ra sự cố trong kiểm tra đơn vị).
ớt

1
Trên một bảng lớn, điều này sẽ gây ra ngoại lệ bộ nhớ vì như @TahirAfridi đã đề cập, điều này sẽ tải tất cả các hàng vào bộ nhớ.
Rihards

6

Bạn có thể sử dụng phạm vi mới nhất do Laravel cung cấp với trường bạn muốn lọc, giả sử nó sẽ được sắp xếp theo ID, sau đó:

Model::latest('id')->first();

Vì vậy, theo cách này, bạn có thể tránh việc đặt hàng theo created_attrường theo mặc định tại Laravel.


5

Để có được các chi tiết hồ sơ cuối cùng, sử dụng mã dưới đây:

Model::where('field', 'value')->get()->last()

Đừng sử dụng nó. Đây là một thực tiễn rất xấu, có một phạm vi mới nhất () nó cung cấp quyền truy cập trực tiếp vào hàng được chèn cuối cùng.
Lợn làm việc

3

Một cách thú vị khác để làm điều đó trong Laravel 6.x (Không chắc chắn nhưng phải hoạt động cho 5.x aswell):

DB::table('your_table')->get()->last();

Bạn cũng có thể truy cập các trường:

DB::table('your_table')->get()->last()->id;


Cũng hoạt động với tôi trong Laravel 5.8, chỉ cần đăng câu trả lời trước khi nhìn thấy bạn
Dazzle

1
Một lời giải thích nhỏ về cách laravel thực hiện điều này đằng sau hiện trường và tại sao điều này nguy hiểm đối với tập dữ liệu lớn, get()phương thức sẽ lấy mọi thứ từ đó your_tablevà tạo Bộ sưu tập và last()phương thức sẽ lấy mục cuối cùng từ bộ sưu tập đó. Vì vậy, bạn sẽ có tất cả dữ liệu từ bảng được tải trên bộ nhớ của bạn (xấu). Bạn chỉ nên sử dụng `DB :: bảng ('mục') -> mới nhất () -> đầu tiên ();` đằng sau cảnh nó thực hiện `orderBy (cột $, 'desc')` và lấy bản ghi đầu tiên.
Anuj Shrestha


1

Nếu bạn đang tìm kiếm hàng thực tế mà bạn vừa chèn bằng Laravel 3 và 4 khi bạn thực hiện một savehoặc createhành động trên một mô hình mới như:

$user->save();

-hoặc là-

$user = User::create(array('email' => 'example@gmail.com'));

sau đó phiên bản mô hình được chèn sẽ được trả về và có thể được sử dụng cho các hành động tiếp theo như chuyển hướng đến trang hồ sơ của người dùng vừa tạo.

Tìm kiếm bản ghi được chèn cuối cùng hoạt động trên hệ thống âm lượng thấp sẽ hoạt động gần như mọi lúc nhưng nếu bạn phải chèn vào cùng một lúc, bạn có thể kết thúc truy vấn để tìm bản ghi sai. Điều này thực sự có thể trở thành một vấn đề trong một hệ thống giao dịch, nơi nhiều bảng cần được cập nhật.


1

Bằng cách nào đó, tất cả những điều trên dường như không hoạt động với tôi trong laravel 5.3, vì vậy tôi đã giải quyết vấn đề của riêng mình bằng cách sử dụng:

Model::where('user_id', '=', $user_id)->orderBy('created_at', 'desc')->get();

hy vọng có thể bảo lãnh một ai đó ra.


1

Sử dụng Model::where('user_id', $user_id)->latest()->get()->first(); nó sẽ chỉ trả lại một bản ghi, nếu không tìm thấy, nó sẽ trở lại null. Hy vọng điều này sẽ giúp.


0

Nếu bảng có trường ngày, thì đây ( User::orderBy('created_at', 'desc')->first();) là giải pháp tốt nhất, tôi nghĩ vậy. Nhưng không có trường ngày, Model ::orderBy('id', 'desc')->first()->id;là giải pháp tốt nhất, tôi chắc chắn.


0

lưu ý rằng last(), latest()không mang tính quyết định nếu bạn đang tìm kiếm một bản ghi tuần tự hoặc sự kiện / theo thứ tự. Các bản ghi cuối cùng / gần đây có thể có cùng created_atdấu thời gian chính xác và việc bạn nhận lại không mang tính quyết định. Vì vậy, làm orderBy(id|foo)->first(). Những ý tưởng / đề xuất khác về cách xác định được hoan nghênh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.