テーブルの最後の行を選択


163

テーブルに挿入された最後のファイルを取得したいのですが。メソッドfirst()が存在し、テーブルの最初のファイルが提供されることは知っていますが、最後の挿入を取得する方法がわかりません。


また、stackoverflow.com / questions / 33321447 /…を参照してください。既存の関係をソートする方法(hasMany)
Tarek Adam

これは、Laravelについて質問したり回答したりするためのものです。話しているLaravelのバージョンを指定することが重要であることを忘れないでください。通常、バージョン4と5には違いがあり、古いバージョンも違います。
ヘロセロヒム2016年

回答:


223

今までに注文したのと同じフィールドで注文する必要がありますが、降順です。例として、アップロードが完了したときにタイムスタンプが呼び出されたupload_time場合は、次のようにします。

Pre-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();

これにより、filesテーブルの行がアップロード時間の降順で並べられ、最初の行が取得されます。これが最新のアップロードファイルになります。


15
Laravel 4の場合orderBy、これはではなく、order_by
Jared Eitnier 2013年

9
:あなたはORMを使用する場合、これは正しい方法であるUser::orderby('created_at', 'desc')->first();
のCas Bloem

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

9
なぜcreated_at列を使用しているのですか?主キーIDを使用する方がはるかに高速です。Laravel 5.x Files::orderBy(id', 'desc')->first();日付順は文字列であり、ほとんどの場合インデックス化されていないため、より長く機能します。主キーにはインデックスが付けられ、超高速で動作します。created_atがインデックス化されている場合でも、プライマリの場合はINTではなく、インデックス化された文字列です。インデックス文字列はパフォーマンスが低下します。
KorbenDallas

4
@KorbenDallasコメントが答えになるはずorderBy('created_at', 'desc')です。最終行が得られない場合があるからです。例:3つの行のTIMESTAMP値はまったく同じorderBy('created_at', 'desc')で、3つ目の最初の行(最後の行とは限りません)を取得できます
viery365

111

Laravelが提供する最新のスコープをそのまま使用します。

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

そうすれば、すべてのレコードを取得することにはなりません。orderByへのより良いショートカット。


7
このメソッドはモデルで自動生成されたcreated_at列を使用し($timestamps = true)ますが、必要に応じて無効にできるため、未定義の場合はエラーが発生することに注意してください
Plotisateur

Laravel 5.7を使用していますが、モデルでこれを実行しようとしても、すべてのレコードが取得されます。
CJデニス

1
同じ秒内に複数のレコードを追加した場合、created_at時刻はこれらのレコードで同じになるため、latest()から返されたレコードは、期待どおりのレコードではない可能性があることに注意してください。
F3CP

「created_at」列は必要ないことに注意してください。どの列から最新にするかを指定できます。例:Model :: latest( 'dateColumn')-> first();
トム

これは、2秒の行が1秒以内に挿入された場合、実際の最後の行の取得に失敗する可能性があります(実際にユニットテストで問題が発生しました)。
チリ

75

LaravelのデフォルトのORMであるEloquentを使用しているかどうかについては言及していません。もしそうなら、created_atでUserテーブルの最新のエントリを取得したいとしましょう。おそらく次のようにすることができます:

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

最初に、created_atフィールドでユーザーを降順に並べ替え、次に結果の最初のレコードを取得します。

これは、コレクションではなく、Userオブジェクトのインスタンスを返します。もちろん、この代替手段を利用するには、Eloquentクラスを拡張するUserモデルが必要です。これは少し混乱するように聞こえるかもしれませんが、始めるのは本当に簡単で、ORMは非常に役立ちます。

詳細については、かなりリッチで詳細な公式ドキュメントをご覧ください。


42

最後のレコードの詳細を取得するには

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

最後のレコードIDを取得するには

  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
Steven Jeffriesのコメントに加えて、呼び出しlast()はコレクションではなく単一のEloquentインスタンスを返し、それpluck()を呼び出すことはを呼び出すことと同じModel::all()->pluck('name')であるため、テーブル内nameすべての行の属性を返すことを指摘したいと思います
ivcandela

5
この方法は実際には悪いです。DBレベルではなく、PHP実行を使用して最後のrawをフェッチしています。テーブルに何百万もの生が含まれているとしたら、それがどれほど非効率になる可能性があるか知っていますか?
Bhaskar Dabhi 2016年

これはそれを行うための最良の方法です。- 番号!今までになかった、決してそうではない。必要な行だけでなく、すべての行をロードます。
ルネ・ロス

11

これを試して :

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

1
これは複数の行を返します。彼は単一の行が必要です。first()は、orderBy()句で彼を助けます。
Tahir Afridi

これは、2秒の行が1秒以内に挿入された場合、実際の最後の行の取得に失敗する可能性があります(実際にユニットテストで問題が発生しました)。
チリ

1
大きなテーブルでは、@ TahirAfridiが言及したように、これによりすべての行がメモリに読み込まれるため、メモリ不足の例外が発生します。
Rihards

6

Laravelが提供する最新のスコープを、フィルタリングするフィールドで使用できます。たとえば、IDで並べ替えるとします。

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

したがって、このようにして、created_atLaravelではデフォルトでフィールドによる順序付けを回避できます。


5

最後のレコードの詳細を取得するには、以下のコードを使用します。

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

使用しないでください。これは非常に悪い習慣で、最後に挿入された行への直接アクセスを提供するスコープlatest()があります。
働くブタ

3

Laravel 6.xでこれを行うもう1つの豪華な方法(不明ですが、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($ column、 'desc')`を実行し、最初のレコードをフェッチするだけです。
Anuj Shrestha


1

次のような新しいモデルでsaveまたはcreateアクションを実行するときに、Laravel 3および4で挿入した実際の行を探している場合:

$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(); すると、1つのレコードのみが返され、見つからない場合はが返されnullます。これがお役に立てば幸いです。


0

テーブルに日付フィールドがある場合、this(User::orderBy('created_at', 'desc')->first();)が最善の解決策だと思います。しかし、日付フィールドはなくModel ::orderBy('id', 'desc')->first()->id;、最善の解決策です。


0

順次またはイベント/順序付きレコードを探している場合last()latest()は確定的ではないことに注意してください。最後/最近のレコードは正確に同じcreated_atタイムスタンプを持つことができ、どのタイムスタンプを取得するかは確定的ではありません。そうですorderBy(id|foo)->first()。決定論的である方法に関する他のアイデア/提案は大歓迎です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.