Seleccione la última fila de la tabla


163

Me gustaría recuperar el último archivo insertado en mi tabla. Sé que el método first()existe y le proporciona el primer archivo de la tabla, pero no sé cómo obtener la última inserción.


Consulte también stackoverflow.com/questions/33321447/… Cómo ordenar una relación existente (hasMany)
Tarek Adam

Esto es para cualquiera que pregunte y responda sobre Laravel. Recuerde que es importante especificar de qué versión de Laravel está hablando. En general, las versiones 4 y 5 tienen diferencias y versiones anteriores también.
Heroselohim

Respuestas:


224

Tendrá que ordenar por el mismo campo que está ordenando ahora, pero descendiendo. Como ejemplo, si tiene una marca de tiempo cuando se realizó la carga upload_time, se haría algo como esto;

Para Pre-Laravel 4

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

Para Laravel 4 y en adelante

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

Para Laravel 5.7 y en adelante

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

Esto ordenará las filas en la tabla de archivos por tiempo de carga, orden descendente y tomará la primera. Este será el último archivo cargado.


15
Para Laravel 4 esto debería ser orderBy, noorder_by
Jared Eitnier

9
Cuando usa ORM, esta es la forma correcta:User::orderby('created_at', 'desc')->first();
Cas Bloem

1
Laravel 5.x =orderBy('created_at', 'desc')
0x1ad2

9
¿Por qué estás usando created_at column? Mucho más rápido para usar la identificación de clave principal. Laravel 5.x Files::orderBy(id', 'desc')->first();Ordenar por fecha funciona más porque la fecha es una cadena y probablemente no esté indexada. Mientras que la clave primaria está indexada y funciona súper rápido. Incluso si created_at está indexado, es una cadena indexada y no INT en el caso de primaria. La cadena de índice tiene menos rendimiento.
KorbenDallas

44
El comentario de @KorbenDallas debería ser la respuesta porque a veces orderBy('created_at', 'desc')no le da la última fila. Ejemplo: 3 filas pueden tener exactamente el mismo valor TIMESTAMP y con orderBy('created_at', 'desc')usted obtendrá la primera de las 3 (que no es necesariamente la última fila)
viery365

111

Use el último alcance proporcionado por Laravel fuera de la caja.

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

De esa manera no estás recuperando todos los registros. Un atajo más agradable para orderBy.


77
Tenga en cuenta que este método utiliza la created_atcolumna generada automáticamente ($timestamps = true)en el Modelo, pero puede deshabilitarse si lo desea, por lo que tendría un error si no está definido
Plotisateur

Estoy usando Laravel 5.7 y tratar de hacer esto en un Modelo todavía recupera todos los registros por mí.
CJ Dennis

1
Tenga en cuenta que si tiene varios registros agregados en el mismo segundo, el tiempo created_at será el mismo para estos registros y, por lo tanto, el registro devuelto por latest () puede no ser el registro que espera que sea.
F3CP

Tenga en cuenta que no necesita una columna 'created_at'. Puede especificar desde qué columna desea la última. Por ejemplo: Model :: latest ('dateColumn') -> first ();
Tom

Esto puede no obtener la última fila real si se insertan dos filas dentro de 1 segundo (en realidad causó problemas en las pruebas unitarias).
Chile

75

Nunca mencionó si está utilizando Eloquent, el ORM predeterminado de Laravel o no. En caso afirmativo, supongamos que desea obtener la última entrada de una tabla de usuario, por created_at, probablemente podría hacer lo siguiente:

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

Primero ordena a los usuarios por el campo created_at, de forma descendente, y luego toma el primer registro del resultado.

Eso le devolverá una instancia del objeto Usuario, no una colección. Por supuesto, para hacer uso de esta alternativa, debe tener un modelo de Usuario, que amplía la clase Eloquent. Esto puede sonar un poco confuso, pero es realmente fácil comenzar y ORM puede ser realmente útil.

Para obtener más información, consulte la documentación oficial que es bastante rica y bien detallada.


42

Para obtener los últimos detalles del registro

  1. Model::all()->last(); o
  2. Model::orderBy('id', 'desc')->first();

Para obtener la última identificación de registro

  1. Model::all()->last()->id; o
  2. Model::orderBy('id', 'desc')->first()->id;

14

Laravel colecciones tiene método pasado

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

Esta es la mejor manera de hacerlo.


16
Solo quería señalar que el all()método en realidad carga todos los elementos. Esto no funcionará en una mesa con millones de registros.
Steven Jeffries

1
Además del comentario de Steven Jeffries, me gustaría señalar que las llamadas last()devuelven una sola instancia Eloquent y no una Colección, y llamar pluck()es igual a llamar Model::all()->pluck('name'), por lo tanto, devuelve el nameatributo de todas las filas de la tabla
ivcandela

55
Este método es peor en realidad. Está obteniendo el último raw usando la ejecución de PHP en lugar de hacerlo como nivel de base de datos. ¿Qué pasa si la mesa tiene millones de primas, entonces sabes cuánto ineficiente puede ser?
Bhaskar Dabhi el

Esta es la mejor manera de hacerlo. - ¡No! Nunca lo ha sido, nunca lo hará. Cargaría todas las filas en lugar de solo la que necesita.
René Roth

11

Prueba esto :

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

1
Esto devolverá varias filas. Necesita una sola fila. first () lo ayudará con la cláusula orderBy ().
Tahir Afridi

Esto puede no obtener la última fila real si se insertan dos filas dentro de 1 segundo (en realidad causó problemas en las pruebas unitarias).
Chile

1
En una tabla grande, esto provocará una excepción de falta de memoria porque, como mencionó @TahirAfridi, esto cargará todas las filas en la memoria.
Rihards

6

Puede usar el último alcance proporcionado por Laravel con el campo que desea filtrar, digamos que se ordenará por ID, luego:

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

De esta manera, puede evitar ordenar por created_atcampo de forma predeterminada en Laravel.


5

Para obtener los últimos detalles del registro, use el siguiente código:

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

No lo uses Esta es una práctica muy mala, hay un alcance último () que proporciona acceso directo a la última fila insertada.
Working Pig

3

Otra forma elegante de hacerlo en Laravel 6.x (No estoy seguro, pero también debe funcionar para 5.x):

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

También puedes acceder a los campos:

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


También funciona para mí en Laravel 5.8, acabo de publicar la respuesta antes de ver la suya
Dazzle

1
Una pequeña explicación sobre cómo laravel hace esto detrás de escena y por qué esto es peligroso para un conjunto de datos grande, el get()método buscará todo your_tabley generará una Colección y el last()método obtendrá el último elemento de esa colección. Entonces ya tendrá todos los datos de la tabla cargados en su memoria (incorrectos). Simplemente debe usar `DB :: table ('items') -> latest () -> first ();` detrás de escena ejecuta `orderBy ($ column, 'desc')` y busca el primer registro.
Anuj Shrestha


1

Si usted está buscando para la fila real que acaba de insertar con laravel 3 y 4 cuando se realiza una saveo createacción en un nuevo modelo como:

$user->save();

-o-

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

entonces la instancia de modelo insertada se devolverá y se puede usar para acciones adicionales como redirigir a la página de perfil del usuario que acaba de crear.

Buscar el último registro insertado que funciona en un sistema de bajo volumen funcionará casi todo el tiempo, pero si alguna vez tiene que insertar inserciones al mismo tiempo, puede terminar consultando para encontrar el registro incorrecto. Esto realmente puede convertirse en un problema en un sistema transaccional donde se deben actualizar varias tablas.


1

De alguna manera, todo lo anterior no parece funcionar para mí en laravel 5.3, así que resolví mi propio problema usando:

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

Espero poder rescatar a alguien.


1

El uso Model::where('user_id', $user_id)->latest()->get()->first(); solo devolverá un registro; si no lo encuentra, volverá null. Espero que esto ayude.


0

Si la tabla tiene un campo de fecha User::orderBy('created_at', 'desc')->first();, creo que esta ( ) es la mejor solución. Pero no hay campo de fecha, Model ::orderBy('id', 'desc')->first()->id;es la mejor solución, estoy seguro.


0

ser conscientes de que last(), latest()no son deterministas si usted está buscando un secuencial o evento de grabación / ordenada. Los últimos / recientes registros pueden tener exactamente la misma created_atmarca de tiempo, y lo que obtiene no es determinista. También lo hacen orderBy(id|foo)->first(). Otras ideas / sugerencias sobre cómo ser determinista son bienvenidas.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.