เลือกแถวสุดท้ายในตาราง


163

ผมอยากจะเรียกไฟล์ที่ผ่านมาแทรกลงในตารางของฉัน ฉันรู้ว่าวิธีการนี้first()มีอยู่และให้ไฟล์แรกในตารางแก่คุณ แต่ฉันไม่ทราบวิธีรับส่วนแทรกครั้งล่าสุด


ดูstackoverflow.com/questions/33321447/วิธีการเรียงลำดับความสัมพันธ์ที่มีอยู่ (hasMany)
Tarek Adam

นี่คือสำหรับทุกคนถามและตอบเกี่ยวกับ Laravel จำไว้ว่าเป็นสิ่งสำคัญที่จะต้องระบุรุ่นของ Laravel ที่คุณกำลังพูดถึง โดยทั่วไปแล้วเวอร์ชัน 4 และ 5 มีความแตกต่างและรุ่นเก่าด้วย
Heroselohim

คำตอบ:


224

คุณจะต้องสั่งซื้อตามฟิลด์เดียวกับที่คุณสั่งซื้อตอนนี้ แต่จากมากไปน้อย ตัวอย่างเช่นหากคุณมีการประทับเวลาเมื่อมีการเรียกการอัปโหลดเสร็จ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();

การดำเนินการนี้จะเรียงลำดับแถวในตารางไฟล์ตามเวลาที่อัพโหลดเรียงลำดับจากมากไปน้อยและใช้ลำดับแรก นี่จะเป็นไฟล์ที่อัปโหลดล่าสุด


15
สำหรับ Laravel 4 ควรเป็นorderByเช่นนี้ไม่ใช่order_by
Jared Eitnier

9
เมื่อคุณใช้ ORM นี่เป็นวิธีที่ถูกต้อง:User::orderby('created_at', 'desc')->first();
Cas Bloem

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

9
ทำไมคุณถึงใช้คอลัมน์ created_at เร็วกว่าการใช้รหัสคีย์หลัก Laravel 5.x การFiles::orderBy(id', 'desc')->first();เรียงลำดับตามวันที่ทำงานได้นานขึ้นเพราะวันที่เป็นสตริงและส่วนใหญ่ไม่ได้จัดทำดัชนี ขณะที่คีย์หลักถูกทำดัชนีและทำงานได้อย่างรวดเร็ว แม้ว่า created_at การจัดทำดัชนีมันเป็นสายอักขระดัชนีและไม่ INT ในกรณีของหลัก สตริงดัชนีมีประสิทธิภาพลดลง
KorbenDallas

4
@ ความคิดเห็น KorbenDallas ควรเป็นคำตอบเพราะบางครั้งorderBy('created_at', 'desc')ไม่ได้ให้แถวสุดท้ายแก่คุณ ตัวอย่าง: 3 แถวสามารถมีค่า TIMESTAMP เท่ากันทุกประการและorderBy('created_at', 'desc')คุณจะได้รับ 1 ใน 3 (ซึ่งไม่จำเป็นต้องเป็นแถวสุดท้าย)
viery365

111

ใช้ขอบเขตล่าสุดที่จัดทำโดย Laravel นอกกรอบ

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

ด้วยวิธีนี้คุณจะไม่ได้รับข้อมูลทั้งหมด ทางลัดที่ดีกว่าในการสั่งซื้อโดย


7
หมายเหตุว่าการใช้วิธีนี้สร้างขึ้นโดยอัตโนมัติcreated_atคอลัมน์($timestamps = true)ในรุ่น แต่สามารถปิดการใช้งานที่ปรารถนาดังนั้นคุณจะต้องข้อผิดพลาดหากไม่ได้กำหนด
Plotisateur

ฉันใช้ Laravel 5.7 และพยายามทำสิ่งนี้ในแบบจำลองยังคงดึงข้อมูลทั้งหมดให้ฉัน
CJ Dennis

1
โปรดทราบว่าหากคุณมีหลายระเบียนที่เพิ่มภายในวินาทีเดียวกันเวลา created_at จะเหมือนกันสำหรับระเบียนเหล่านี้และดังนั้นระเบียนที่ส่งคืนโดยล่าสุด () อาจไม่ใช่ระเบียนที่คุณคาดว่าจะเป็น
F3CP

โปรดทราบว่าคุณไม่จำเป็นต้องมีคอลัมน์ 'created_at' คุณสามารถระบุได้จากคอลัมน์ใดที่คุณต้องการล่าสุด ตัวอย่างเช่น: Model :: latest ('dateColumn') -> first ();
Tom

สิ่งนี้อาจล้มเหลวในการรับแถวสุดท้ายที่แท้จริงหากมีการแทรกสองแถวภายใน 1 วินาที (เกิดปัญหาจริงในการทดสอบหน่วย)
พริก

75

คุณไม่เคยพูดถึงว่าคุณกำลังใช้ Eloquent ORM เริ่มต้นของ Laravel หรือไม่ ในกรณีที่คุณเป็นเช่นสมมติว่าคุณต้องการรับรายการล่าสุดของตารางผู้ใช้โดย created_at คุณอาจทำได้ดังนี้:

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

ก่อนอื่นให้เรียงลำดับผู้ใช้ตามฟิลด์ created_at จากมากไปน้อยจากนั้นจะบันทึกครั้งแรกของผลลัพธ์

ซึ่งจะส่งคืนอินสแตนซ์ของวัตถุผู้ใช้ของคุณไม่ใช่คอลเล็กชัน แน่นอนในการใช้ประโยชน์จากทางเลือกนี้คุณต้องมีโมเดลผู้ใช้ซึ่งขยายคลาส Eloquent สิ่งนี้อาจฟังดูสับสนเล็กน้อย แต่มันง่ายในการเริ่มต้นและ 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()วิธีการโหลดรายการทั้งหมดจริง ๆ แล้ว สิ่งนี้จะไม่ทำงานบนโต๊ะที่มีบันทึกนับล้าน
Steven Jeffries

1
นอกเหนือไปจากสตีเว่นเจฟฟรีส์แสดงความคิดเห็นผมอยากจะชี้ให้เห็นว่าการเรียกร้องlast()ผลตอบแทนเช่นฝีปากเดียวและไม่ได้เป็นคอลเลกชันและเรียกpluck()ว่ามีค่าเท่ากับการเรียกModel::all()->pluck('name')จึงกลับมาnameแอตทริบิวต์ของทุกแถวในตาราง
ivcandela

5
วิธีนี้แย่กว่าจริง คุณกำลังดึงข้อมูลดิบครั้งล่าสุดโดยใช้การประมวลผล PHP แทนที่จะทำในระดับฐานข้อมูล ถ้าตารางมีล้านดิบคุณจะรู้ว่ามันไม่มีประสิทธิภาพเท่าไหร่
Bhaskar Dabhi

นี่เป็นวิธีที่ดีที่สุดที่จะทำ - ไม่! ไม่เคยจะไม่เคยจะ คุณต้องการโหลดแถวทั้งหมดแทนที่จะเป็นแถวที่คุณต้องการ
René Roth

11

ลองสิ่งนี้:

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

1
นี่จะส่งคืนแถวจำนวนมาก เขาต้องการแถวเดียว first () จะช่วยเขาด้วย orderBy () ข้อ
Tahir Afridi

สิ่งนี้อาจล้มเหลวในการรับแถวสุดท้ายที่แท้จริงหากมีการแทรกสองแถวภายใน 1 วินาที (เกิดปัญหาจริงในการทดสอบหน่วย)
พริก

1
บนตารางขนาดใหญ่สิ่งนี้จะทำให้เกิดข้อยกเว้นหน่วยความจำเนื่องจากเนื่องจาก @TahirAfridi ที่กล่าวถึงนี้จะโหลดแถวทั้งหมดลงในหน่วยความจำ
Rihards

6

คุณสามารถใช้ขอบเขตล่าสุดที่ Laravel จัดหาให้กับเขตข้อมูลที่คุณต้องการกรองสมมติว่าจะมีการสั่งซื้อโดย ID จากนั้น:

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') -> ล่าสุด () -> first ();` หลังฉากมันทำงานได้ `orderBy ($ column, 'desc') 'และดึงเอาเรคคอร์ดแรก
Anuj Shrestha


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()นั้น ยินดีต้อนรับแนวคิด / คำแนะนำอื่น ๆ เกี่ยวกับวิธีการกำหนดค่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.