【问题标题】:Select Last Row in the Table选择表格中的最后一行
【发布时间】:2013-05-14 17:38:53
【问题描述】:

我想检索插入到我的表中的最后一个文件。我知道 first() 方法存在并为您提供表中的第一个文件,但我不知道如何获取最后一个插入。

【问题讨论】:

  • 另见stackoverflow.com/questions/33321447/…如何对现有关系进行排序(hasMany)
  • 这是为任何询问和回答有关 Laravel 的人准备的。请记住,指定您正在谈论的 Laravel 版本很重要。通常版本 4 和 5 和旧版本也有差异。

标签: laravel eloquent


【解决方案1】:

立即使用 Laravel 提供的最新范围。

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

这样您就不会检索所有记录。一个更好的 orderBy 快捷方式。

【讨论】:

  • 请注意,此方法使用模型中自动生成的created_at($timestamps = true),但可以随意禁用,因此如果未定义会出错
  • 我正在使用 Laravel 5.7 并尝试在模型上执行此操作仍然为我检索所有记录。
  • 请注意,如果您在同一秒内添加了多条记录,则这些记录的 created_at 时间将相同,因此 latest() 返回的记录可能不是您期望的记录.
  • 请注意,您不需要“created_at”列。您可以从您想要最新的列中指定。例如:Model::latest('dateColumn')->first();
  • 如果在1秒内插入两行,可能无法获取实际的最后一行(实际上是在单元测试中引起问题)。
【解决方案2】:

您需要按您现在订购的同一字段进行排序,但要降序排列。 例如,如果您在上传完成时有一个名为 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();

这将按上传时间降序对文件表中的行进行排序,并取第一个。这将是最新上传的文件。

【讨论】:

  • 对于 Laravel 4,这应该是 orderBy,而不是 order_by
  • 在使用ORM时,这是正确的方式:User::orderby('created_at', 'desc')->first();
  • Laravel 5.x = orderBy('created_at', 'desc')
  • 你为什么使用 created_at 列?使用主键 ID 更快。 Laravel 5.x Files::orderBy(id', 'desc')->first(); 按日期排序的工作时间更长,因为日期是字符串并且很可能没有索引。虽然主键被索引并且工作速度超快。即使 created_at 被索引,它也是索引字符串而不是 INT 在主要的情况下。索引字符串的性能较差。
  • @KorbenDallas 评论应该是答案,因为有时orderBy('created_at', 'desc') 不会给你最后一行。示例:3 行可以具有完全相同的 TIMESTAMP 值,使用 orderBy('created_at', 'desc') 您将获得 3 行中的第一个(不一定是最后一行)
【解决方案3】:

许多答案和一些我不太同意的地方。所以我再用我的cmets总结一下。

如果您刚刚创建了一个新对象。 默认情况下,当你创建一个新对象时,Laravel 会返回这个新对象。

$lastCreatedModel = $model->create($dataArray); 

dd($lastCreatedModel); // will output the new output
echo $lastCreatedModel->key; // will output the value from the last created Object

还有一种方法是在没有条件的情况下将all() 与 (last()and first()) 方法结合起来。

非常糟糕!不要那样做!

Model::get()->last();` // the most recent entry
Model::all()->last();` // the most recent entry

Model::get()->first();` // the oldest entry
Model::all()->first();` // the oldest entry

这基本上是错误的方法!你get()all() 记录,在某些情况下可能是 200,000 或更多,然后只挑出一行。不好!想象一下,您的网站正在从 Facebook 获得流量,然后是这样的查询。在一个月内,这可能意味着像巴黎这样的城市一年的二氧化碳排放量。因为服务器必须不必要地努力工作。所以忘记这种方法,如果你在你的代码中找到它,替换它/重写它。也许你不会注意到 100 个数据集,但如果有 1000 个或更多数据集,它就会很明显。

非常好:

Model::orderBy('id', 'desc')->last(); // the most recent record
Model::latest('id')->first(); // the most recent record
Model::latest('id')->limit(1)->get(); // the most recent record
Model::orderBy('id', 'desc')->limit(1)->get(); // the most recent entry
Model::orderBy('id', 'desc')->first(); // the most recent entry

Model::orderBy('id', 'asc')->first(); // the oldest entry
Model::orderBy('id', 'asc')->limit(1)->get(); // the oldest entry
Model::orderBy('id', 'asc')->first(); // the oldest entry

如果在此上下文中使用 orderBy,则应始终将主键用作基础,而不是 create_at。

【讨论】:

    【解决方案4】:

    获取最后一条记录的详细信息

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

    获取最后一条记录id

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

    【讨论】:

    • 如果你使用第一个选项,你可能会让你的 PHP 死掉,试图在它拥有的可用内存中分配信息。它基本上获取整个表,为每条记录创建一个实例,并将其存储在 RAM 中。然后,它只获取最后一条记录,但前提是 PHP 还没有死。第二种方法是有效的,因为它只从数据库中获取必要的信息。
    【解决方案5】:

    您可以使用 Laravel 提供的最新范围与您要过滤的字段,假设它会按 ID 排序,那么:

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

    所以通过这种方式,你可以避免在 Laravel 默认按created_at 字段排序。

    【讨论】:

    • 如果 id 是 uuid 怎么办?
    • @BariqDharmawan 你可以做Model::latest('uuid')->first() 或任何你想要的字段。
    • 哇 IDK latest() 方法与 uuid 一起使用。 Bcz 我认为这是一个完全随机的字符串,不能按 asc 排序。谢谢
    【解决方案6】:

    你从来没有提到你是否使用 Eloquent,Laravel 的默认 ORM。如果您是,假设您想通过 created_at 获取 User 表的最新条目,您可能可以执行以下操作:

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

    首先它按 created_at 字段对用户进行降序排序,然后取结果的第一条记录。

    这将返回一个 User 对象的实例,而不是一个集合。当然,要使用这个替代方案,你必须有一个 User 模型,扩展 Eloquent 类。这可能听起来有点令人困惑,但它非常容易上手,而且 ORM 真的很有帮助。

    如需更多信息,请查看official documentation,内容丰富且详细。

    【讨论】:

    • 这会引发错误,我的列“video_title”是 STRING 类型,Attempt to read property "video_title" on bool 它也是 2021 年(这可能是一个旧答案)并且我使用 Laravel 8,谢谢!
    • 例如在用户模型中的 realtionship $this->posts()->latest()->first()
    【解决方案7】:

    老实说,这太令人沮丧了,我几乎不得不在这里浏览整个答案集合,才能发现他们中的大多数人没有做我想做的事。事实上,我只想向浏览器显示以下内容:

    1. 在我的表上创建的最后一行
    2. 只有 1 个资源

    我不希望对一组资源进行排序并以降序排列该列表,下面的代码行在 Laravel 8 项目中对我有用。

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

    【讨论】:

      【解决方案8】:

      不要使用Model::latest()->first();,因为如果您的集合在同一时间戳创建了多行(当您使用数据库事务DB::beginTransaction();DB::commit() 时会发生这种情况),那么将返回集合的第一行并且显然这不会是最后一行。

      假设 id 为 11、12、13 的行是使用事务创建的,那么它们都将具有相同的时间戳,因此您将通过 Model::latest()->first(); 获得 id 为 11 的行。

      【讨论】:

      • @Mohammad 正确的做法是:Model::orderBy('id', 'desc')->first();这里的'id'是表的主键(自增)。
      【解决方案9】:

      对于 laravel 8

      Model::orderBy('id', 'desc')->withTrashed()->take(1)->first()->id
      

      生成的 sql 查询:

      Model::orderBy('id', 'desc')->withTrashed()->take(1)->toSql()
      

      select * from "timetables" order by "id" desc limit 1

      【讨论】:

        【解决方案10】:

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

        【讨论】:

          【解决方案11】:

          请注意,last()latest() 在查找顺序或事件/有序记录时不是确定性的。最后/最近的记录可以具有完全相同的created_at 时间戳,而您返回的时间戳是不确定的。 orderBy(id|foo)->first() 也是如此。欢迎提出其他关于如何确定性的想法/建议。

          【讨论】:

            【解决方案12】:

            使用Model::where('user_id', $user_id)->latest()->get()->first(); 它只会返回一条记录,如果找不到,它将返回null。 希望这会有所帮助。

            【讨论】:

              【解决方案13】:

              在 Laravel 6.x 中实现它的另一种奇特方式(不确定,但也必须适用于 5.x):

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

              您也可以访问字段:

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

              【讨论】:

              • 在 Laravel 5.8 中也适用于我,只是在看到你之前发布了答案
              • 稍微解释一下 laravel 如何在幕后做这件事以及为什么这对大型数据集很危险,get() 方法将从your_table 获取所有内容并生成一个集合,last() 方法将从该集合中获取最后一项。因此,您已经将表中的所有数据加载到您的内存中(坏)。您应该只使用 `DB::table('items')->latest()->first();` 在幕后执行 `orderBy($column, 'desc')` 并获取第一条记录。跨度>
              【解决方案14】:

              要获取最后一条记录的详细信息,请使用以下代码:

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

              【讨论】:

              • 不要使用它。这是一个非常糟糕的做法,有一个范围 latest() 它提供对最后插入的行的直接访问。
              【解决方案15】:

              如果您正在寻找刚刚在 Laravel 3 和 4 中插入的实际行,当您对新模型执行 savecreate 操作时:

              $user->save();
              

              -或-

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

              然后插入的模型实例将被返回,并可用于进一步的操作,例如重定向到刚刚创建的用户的个人资料页面。

              在低容量系统上查找最后插入的记录几乎一直有效,但如果您必须同时插入,您最终可能会查询以找到错误的记录。在需要更新多个表的事务系统中,这确实会成为一个问题。

              【讨论】:

                【解决方案16】:

                Laravel 集合有最后一个方法

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

                这是最好的方法。

                【讨论】:

                • 只是想指出all() 方法实际上加载了所有项目。这不适用于具有数百万条记录的表。
                • 除了 Steven Jeffries 的评论,我想指出调用 last() 返回单个 Eloquent 实例而不是 Collection,并且调用 pluck() 等于调用 Model::all()->pluck('name') ,因此返回表中所有行的name属性
                • 这种方法实际上更糟糕。您正在使用 PHP 执行而不是作为数据库级别来获取最后一个原始数据。如果 table 有数百万个 raw,那你知道它的效率有多低吗?
                • 这是最好的方法。 - 不!从来没有,永远不会。您将加载 所有 行,而不仅仅是您需要的那一行。
                • 喜欢这个 bcz 如果您的表没有 created_at 或任何类似的列,这不需要任何时间戳列
                【解决方案17】:

                试试这个:

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

                【讨论】:

                • 这将返回多行。他需要单排。 first() 将帮助他处理 orderBy() 子句。
                • 如果在1秒内插入两行,可能无法获取实际的最后一行(实际上是在单元测试中引起问题)。
                • 在大表上,这将导致内存不足异常,因为正如@TahirAfridi 提到的那样,这会将所有行加载到内存中。
                【解决方案18】:

                不知何故,以上所有内容在 laravel 5.3 中似乎对我不起作用, 所以我解决了我自己的问题:

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

                希望能够保释某人。

                【讨论】:

                  【解决方案19】:

                  如果表格有日期字段,我认为这(User::orderBy('created_at', 'desc')->first();) 是最好的解决方案。 但是没有日期字段,Model ::orderBy('id', 'desc')->first()->id; 是最好的解决方案,我敢肯定。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2013-05-09
                    • 1970-01-01
                    • 2016-04-23
                    • 1970-01-01
                    • 2015-05-11
                    • 2013-04-07
                    • 2011-04-30
                    • 1970-01-01
                    相关资源
                    最近更新 更多