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.

Carlos Suñol
fuente
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.

Joachim Isaksson
fuente
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.

Mella
fuente
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.

Luis Milanese
fuente
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;
Haseena PA
fuente
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.

mdamia
fuente
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();
Mark-Hero
fuente
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.

tiaguinhow
fuente
5

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

Model::where('field', 'value')->get()->last()
Jimuel Palaca
fuente
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;

Toalla
fuente
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
2

Model($where)->get()->last()->id

Deslumbrar
fuente
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' => '[email protected]'));

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.

bloggidy
fuente
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.

El hombre muerto
fuente
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.

风声 猎猎
fuente
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.

wang xin
fuente
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.

mangonights
fuente