【问题标题】:Fetch only last matched row from joined table in Laravel 8 eloquent using table join使用表连接从 Laravel 8 eloquent 中的连接表中仅获取最后匹配的行
【发布时间】:2021-10-03 04:04:21
【问题描述】:

我有 2 张桌子 booking_orders(id)booking_order_status_history(id, order_id,status, created_at) 其中booking_order_status_history.order_id = booking_orders.id 可能有不止一行具有相同的 order_id 但我需要获取最新的行。我正在使用 laravel 雄辩的查询

BookingOrders::select("booking_orders.*", "booking_order_status_history.status as status")
  ->join('booking_order_status_history', 'booking_order_status_history.order_id', '=', 'booking_orders.id'))
->get()

这是从 booking_order_status_history 的保存匹配行中加载所有行。

如何仅获取最后插入的 status 行。谢谢

【问题讨论】:

    标签: mysql laravel eloquent


    【解决方案1】:

    如果您坚持只使用一个查询检索所有结果,并使用连接,您可以使用此查询:

     BookingOrder::query()
                ->join('booking_order_status_history', 'booking_order_status_history.order_id', '=', 'booking_order_status_history.order_id')
                ->where('booking_order_status_history.id', '=', DB::raw("select MAX(booking_order_status_history.id) from booking_order_status_history where booking_order_status_history.order_id = booking_orders.id"))
                ->get();
    

    但我完全鼓励您使用 laravel eloquent 关系解决方案,这当然会花费您额外的查询。但带来了干净的代码。

    // Define Orders Model
    class BookingOrder extends Model
    {
        public function latestStatus()
        {
            return $this->hasOne(BookingOrderStatusHistory::class)->latestOfMany();
        }
    }
    
    // Define History Model
    class BookingOrderStatusHistory extends Model
    {
        //
    }
    
    // Retrieve data in controller
    $orders = BookingOrder::query()->with('latestStatus')->get();
    
    foreach ($orders as $order){
        echo $order->latestStatus->status;
    }
    

    【讨论】:

      【解决方案2】:

      嗯,有很多方法可以做到这一点。其中之一是使用GROUP BY booking_orders.id LIMIT 1,使用 Laravel Query Builder 会如下所示:

      BookingOrders::select("booking_orders.*", "booking_order_status_history.status as status")
        ->join('booking_order_status_history', 'booking_order_status_history.order_id', '=', 'booking_orders.id'))
        ->groupBy('booking_orders.id')
        ->orderByDesc('booking_order_status_history.id')
        ->limit(1)
      ->get();
      

      但如果您使用的是非顺序 ID 生成器(例如UUID)并且您的booking_order_status_history 表有created_at,您可以使用lastest Laravel 方法获取在此表中插入的最后一行,您的查询将如下所示:

      BookingOrders::select("booking_orders.*", "booking_order_status_history.status as status")
        ->join('booking_order_status_history', 'booking_order_status_history.order_id', '=', 'booking_orders.id'))
        ->latest('booking_order_status_history.created_at');
      

      还有很多其他方法可以满足您的需求。

      【讨论】:

        猜你喜欢
        • 2021-07-18
        • 2013-01-21
        • 2020-11-06
        • 1970-01-01
        • 2013-05-17
        • 2014-08-12
        • 1970-01-01
        • 2018-11-06
        • 2019-12-06
        相关资源
        最近更新 更多