首页 > 解决方案 > Laravel 根据子表获取“已完成”行的列表

问题描述

这是我无法弄清楚的问题:
我有一个 Clients 表和一个 Boxes 表。
每个盒子都属于一个客户。
我需要显示属于每个客户端的所有 Box 都已完成的所有客户端,这基本上是 WHERE box.status = "Completed"。

我无法在一个查询中掌握如何做到这一点:
- 获取所有客户端
- 获取属于每个客户端的所有框的计数 ($totalBoxes) - 获取
属于每个客户端的已完成框的计数 ($completedBoxes)
-计算 $completedBoxes = $totalBoxes
- 仅显示 $completedBoxes = $totalBoxes 的客户

我用它来获取 Client.id = 2 的 $totalBoxes 的数量

Client::leftJoin('boxes', 'clients.id','=', 'boxes.clients_id')  
          ->where('clients_id','=',2)  
          ->select('clients.id','boxes.clients_id','boxes.status as status')  
          ->count();  

我用它来获取 Client.id = 2 的 $completedBoxes 的数量

Client::leftJoin('boxes', 'clients.id','=', 'boxes.clients_id')  
          ->where('clients_id','=',2)  
          ->where('boxes.status','=',"Completed")  
          ->select('clients.id','boxes.clients_id','boxes.status as status')  
          ->count();  
if ($completedBoxes == $totalBoxes) {  
   //echo Client row..  
}  

我只是不知道如何在客户端行的主查询/循环中动态执行这些子查询..

例子:

客户 (id)
1
2
3

Boxes (id, client_id, status)
1,1,Processing
2,1,Completed
3,2,Completed
4,2,Completed
5,3,Processing
6,3,Completed

所以我的预期结果是:

已完成客户名单-客户
2

非常感谢您的帮助,非常感谢!

编辑

嘿下巴 - 非常感谢,这帮助我得到了我需要的东西!我最终在我的控制器中使用了以下代码,它返回了我想要的结果。但是,在刀片中显示它的最佳方式是什么?

$clients = Client::all();

foreach ($clients as $client){
  $active = $client->boxes()
        ->where('status', '!=' ,'Shipping')
        ->select('client_id')
        ->orderBy('client_id')
        ->distinct()
        ->get();
  echo $active;
}

我希望做这样的事情:

$completedClients = Client::boxes()
        ->where('status', '!=' ,'Shipping')
        ->select('client_id')
        ->orderBy('client_id')
        ->distinct()
        ->get();

然后我就可以在我的刀片中运行我的循环,但是 Client::boxes 是不正确的语法。在您引用的链接中,示例是 find(1),但我需要它为每个客户端运行。

再次感谢!

编辑 2
嘿,很抱歉回复晚了,我注意到最初提出的解决方案没有返回正确的结果这是我最新的代码:

$completed = Client::whereHas('boxes', function (Builder $query) {
                      $query->where('status', '=', 'Shipping');
                    })
                    ->select('id')
                    ->orderBy('id','asc')
                    ->distinct()
                    ->get();

所以问题是它返回了一个任何 Box.status = Completed 的客户端。我只需要返回 ALL Boxes = Completed 的客户。在我原来的帖子中,应该返回的示例客户端是客户端 #2,因为他们所有的盒子 = 已完成。

标签: mysqllaraveleloquent

解决方案


试试这个:https ://laravel.com/docs/5.8/eloquent-relationships#one-to-many

在 Client 模型中添加如下内容:

public function Boxes() {
    return $this->hasMany('App\Box');
}

在控制器中是这样的:

$clients = Client::all();
return $clients->Boxes()->where('status', 'Completed')->get();

推荐阅读