Виберіть Останній рядок у таблиці


163

Я хотів би отримати останній файл, вставлений у свою таблицю. Я знаю, що метод first()існує і надає вам перший файл у таблиці, але я не знаю, як отримати останню вставку.


Також дивіться stackoverflow.com/questions/33321447/… Як упорядкувати існуючі відносини (hasMany)
Тарек Адам

Це для тих, хто запитує і відповідає про Laravel. Пам'ятайте, що важливо вказати, про яку версію Laravel ви говорите. Як правило, версії 4 і 5 мають відмінності і в старих версіях.
Героселохім

Відповіді:


224

Вам потрібно буде замовити те саме поле, яке ви замовляєте на даний момент, але у спадному порядку. Наприклад, якщо у вас є штамп часу, коли завантаження було здійснено upload_time, ви зробите щось подібне;

Для попереднього Laravel 4

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

Для Laravel 4 і далі

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

Для Laravel 5.7 і далі

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

Це дозволить впорядкувати рядки в таблиці файлів за часом завантаження, порядку зменшення та приймати перший. Це буде останній завантажений файл.


15
Для Laravel 4 це повинно бути orderBy, а неorder_by
Джаред Етьньє

9
Коли ви використовуєте ORM, це правильний спосіб:User::orderby('created_at', 'desc')->first();
Cas Bloem

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

9
Чому ви використовуєте стовпець create_at? Набагато швидше використовувати ідентифікатор первинного ключа. Laravel 5.x Files::orderBy(id', 'desc')->first();Порядок на дату працює довше, оскільки дата є рядовою і, швидше за все, не індексується. У той час як первинний ключ індексується і працює дуже швидко. Навіть якщо create_at індексується, він є індексованим рядком, а не INT у разі первинного. Індексний рядок має меншу продуктивність.
KorbenDallas

4
Коментар @KorbenDallas має бути відповіддю, оскільки іноді orderBy('created_at', 'desc')не дає останнього рядка. Приклад: 3 рядки можуть мати точно однакове значення TIMESTAMP, і orderBy('created_at', 'desc')ви отримаєте перший з 3 (що не обов'язково є останнім рядком)
viery365

111

Використовуйте останню область, яку надає Laravel поза коробкою.

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

Таким чином, ви не отримуєте всі записи. Приємніший ярлик на замовлення.


7
Зауважте, що цей метод використовує автоматично сформований created_atстовпець ($timestamps = true)у Моделі, але його можна відключити за бажанням, щоб ви мали помилку, якщо не визначено
Plotisateur

Я використовую Laravel 5.7 і намагаюся зробити це на Моделі, як і раніше, отримує всі записи для мене.
CJ Dennis

1
Зауважте, що якщо ви додали кілька записів протягом однієї секунди, час create_at буде однаковим для цих записів, тому запис, повернутий останнім часом (), може бути не тим записом, який ви очікуєте.
F3CP

Зауважте, що вам не потрібен стовпець 'created_at'. Ви можете вказати, з якого стовпця ви хочете останню інформацію. Наприклад: Model :: latest ('dateColumn') -> first ();
Том

Це може не отримати фактичний останній рядок, якщо два рядки будуть вставлені протягом 1 секунди (фактично спричинили проблеми при тестуванні одиниць).
чилі

75

Ви ніколи не згадували, використовуєте ви красномовний, ORM за замовчуванням Laravel чи ні. Якщо у вас є, скажімо, ви хочете отримати останню запис таблиці користувача від create_at, ви, ймовірно, можете зробити так:

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

Спочатку він упорядковує користувачів за полем create_at у спадному порядку, а потім бере перший запис результату.

Це поверне вам екземпляр користувача, а не колекцію. Звичайно, щоб скористатися цією альтернативою, ви повинні мати модель користувача, що розширює красномовний клас. Це може здатися дещо заплутаним, але почати дійсно легко, і ORM може бути дуже корисною.

Для отримання додаткової інформації ознайомтеся з офіційною документацією, яка є досить багатою та детальною.


42

Щоб отримати останні дані про запис

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

Щоб отримати останній ідентифікатор запису

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

14

У колекціях Laravel останній метод

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

Це найкращий спосіб зробити це.


16
Просто хотів зазначити, що all()метод фактично завантажує всі елементи. Це не працюватиме на таблиці з мільйонами записів.
Стівен Джеффріс

1
На додаток до коментаря Стівена Джеффріса, я хотів би зазначити, що виклик last()повертає один красномовний екземпляр, а не Колекцію, і заклик, pluck()що дорівнює виклику Model::all()->pluck('name'), тому повертає nameатрибут усіх рядків у таблиці
ivcandela

5
Цей метод насправді гірший. Ви отримуєте останню сировину, використовуючи виконання PHP, а не виконуючи це як рівень БД. Що робити, якщо на столі є мільйони сировини, то ви знаєте, наскільки це може бути неефективно?
Бхаскар Дабхі

Це найкращий спосіб зробити це. - Немає! Ніколи не було, ніколи не буде. Ви завантажуєте всі рядки, а не лише потрібну.
Рене Рот

11

Спробуйте це :

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

1
Це поверне кілька рядків. Йому потрібен один ряд. Перший () допоможе йому у пункті orderBy ().
Тахір Африді

Це може не отримати фактичний останній рядок, якщо два рядки будуть вставлені протягом 1 секунди (фактично спричинили проблеми при тестуванні одиниць).
чилі

1
У великій таблиці це не спричинить виключення пам'яті, оскільки, як згадував @TahirAfridi, це завантажить усі рядки в пам'ять.
Ріхардс

6

Ви можете використовувати останню область, надану Laravel, із полем, яке ви хочете відфільтрувати, скажімо, це буде впорядковано за ідентифікатором, а потім:

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

Таким чином, ви можете уникнути замовлення за created_atполями за замовчуванням у Laravel.


5

Щоб отримати останні дані про запис, скористайтеся кодом нижче:

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

Не використовуйте його. Це дуже погана практика. Є найновіша область застосування (), яка забезпечує прямий доступ до останнього вставленого рядка.
Робоча свиня

3

Ще один химерний спосіб зробити це в Laravel 6.x (Не впевнений, але повинен працювати і для 5.x):

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

Ви також можете отримати доступ до полів:

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


Також працює для мене в Laravel 5.8, щойно опублікував відповідь, перш ніж побачити вашу
Dazzle

1
Невелике пояснення того, як laravel робить це за кадром і чому це небезпечно для великого набору даних, get()метод вибере все з your_tableі створить колекцію, а last()метод отримає останній елемент із цієї колекції. Таким чином, ви вже матимете всі дані з таблиці, завантажені на вашу пам’ять (погано). Вам слід просто скористатися `DB :: table ('items') -> latest () -> first ();` за сценою воно виконує `orderBy (стовпець $, desc ')` і витягує перший запис.
Ануй Шреща


1

Якщо ви шукаєте фактичний рядок, який ви щойно вставили за допомогою Laravel 3 і 4, виконуючи а saveчи createдію на новій моделі, наприклад:

$user->save();

або

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

тоді вставлений екземпляр моделі буде повернутий і може бути використаний для подальших дій, таких як перенаправлення на сторінку профілю щойно створеного користувача.

Шукання останніх вставлених записів працює в системі з низьким рівнем гучності, буде працювати майже весь час, але якщо вам коли-небудь доведеться вставляти вхід одночасно, ви можете закінчити запит, щоб знайти неправильну запис. Це дійсно може стати проблемою в транзакційній системі, де потрібно оновити кілька таблиць.


1

Якось усе вище, здається, не працює для мене в laravel 5.3, тому я вирішив власну проблему, використовуючи:

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

сподіваюся, що вдасться когось викупити.


1

Використовувати Model::where('user_id', $user_id)->latest()->get()->first(); це поверне лише один запис, якщо не знайде, він повернеться null. Сподіваюсь, це допоможе.


0

Якщо в таблиці є поле дати User::orderBy('created_at', 'desc')->first();, я думаю , що це ( ) - найкраще рішення. Але немає поля дати, Model ::orderBy('id', 'desc')->first()->id;це найкраще рішення, я впевнений.


0

мати в вигляді , що last(), latest()не є детермінованим , якщо ви шукаєте послідовний або подія / замовлену запис. Останні / останні записи можуть мати точно таку ж created_atчасову позначку, і яку ви отримаєте назад, не є детермінованою. Так і робити orderBy(id|foo)->first(). Інші ідеї / пропозиції, як бути детермінованими, вітаються.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.