Laravel Eloquent ORM方法,用于基于ID数组检索多行



我可能没有按照我想要的方式表达这个问题,但这是我的困境:

我有一个名为"client"的用户表,其结构如下:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<table class="tg">
<tr>
<th class="tg-yw4l">id</th>
<th class="tg-yw4l">int(10)</th>
<th class="tg-031e">unsigned</th>
</tr>
<tr>
<td class="tg-yw4l">client_name</td>
<td class="tg-yw4l">varchar(255)</td>
<td class="tg-yw4l"></td>
</tr>
<tr>
<td class="tg-yw4l">id_number</td>
<td class="tg-yw4l">int(11)</td>
<td class="tg-yw4l"></td>
</tr>
<tr>
<td class="tg-yw4l">email</td>
<td class="tg-yw4l">varchar(255)</td>
<td class="tg-yw4l"></td>
</tr>
</table>

我有另一个策略"策略"表,结构如下:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<table class="tg">
<tr>
<th class="tg-yw4l">id</th>
<th class="tg-yw4l">int(10)</th>
<th class="tg-yw4l">unsigned</th>
<th class="tg-031e">AUTO INCREMENT</th>
</tr>
<tr>
<td class="tg-yw4l">client_id</td>
<td class="tg-yw4l">int(10)</td>
<td class="tg-yw4l"></td>
<td class="tg-yw4l"></td>
</tr>
<tr>
<td class="tg-yw4l">type_id</td>
<td class="tg-yw4l">int(11)</td>
<td class="tg-yw4l"></td>
<td class="tg-yw4l"></td>
</tr>
<tr>
<td class="tg-yw4l">product_id</td>
<td class="tg-yw4l">int(11)</td>
<td class="tg-yw4l"></td>
<td class="tg-yw4l"></td>
</tr>
</table>

">

策略"表中的"client_id"等同于"客户端"表中的"id"。一个客户端可以有多个"策略"。当策略过期时,我想获取具有过期策略的客户端列表。逻辑是并非每个用户都有过期或即将过期的策略,但一个用户可以有多个过期和过期的策略。(例如,在包含 10 个客户端和总共 20 个即将过期或过期的策略的表中,可能有 5 个客户端具有过期或过期的策略等。每个策略都绑定到一个客户端。该客户端可以有无限数量的策略

考虑到客户端的"id"等于策略表中的"client_id",我应该如何计算策略即将过期的客户端数量?

这是我到目前为止尝试过的:

$today = Carbon::today()->toDateString();
$yesterday = Carbon::yesterday()->toDateString();
$expiry_period = Carbon::today()->addDays(3)->toDateString();
$client = DB::table('clients')->join('active_policies', 'clients.id', '=', 'active_policies.client_id')->select('clients.id');
$active_clients = Clients::all();
$policies = ActivePolicies::all();
$total_policies = $policies->count();
$expiring = $policies->where('renewal_date', '<=', $expiry_period)->where('renewal_date', '>=', $today);
$total_expiring = $expiring->count();
$expired = $policies->where('renewal_date', '<=', $yesterday);
$total_expired = $expired->count();
//here's where I try to count the clients with expiring policies.
$with_expiring = $expiring->where('client_id', '=', DB::table('clients')->get('clients.id'))->count();
//here's where I try to count the clients with expired policies.
$with_expired = $expired->where('client_id', '=', DB::table('clients')->get('clients.id'))->count();

我在执行时收到以下错误:

类型错误:传递给 Illuminate\Database\Grammar::columnize() 的参数 1 必须是给定的数组类型,字符串,在第 131 行的/var/.../app/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php 中调用

DB::table('clients')->get('clients.id')返回Collection$expired->where('client_id', '=', '<this should be string>')

尝试:$expiring->where('client_id', '=', DB::table('clients')->get('clients.id')->first())->count()

但是,该代码不会提供您想要的内容。

您应该创建 Eloquent 模型并使用它,而不是使用DB立面编写查询。

请参阅此处以了解如何定义雄辩模型 https://laravel.com/docs/5.4/eloquent#defining-models

定义ClientEloquent 模型后,可以通过以下方式检索所有客户端:

$clients = Client::whereIn('id', [1, 2, 3]); // where 1,2,3 is the client ids

这似乎可以解决问题:

/*groups the expiring policies for each user*/
$with_expiring = $expiring->groupBy('client_id');
/*counts the number of clients with expiring policies instead of
*counting the number of expiring policies first then checking
*against a list of 'client_id's
*/
$total_with_expiring = $with_expiring->count();
/*groups the expired policies for each user*/
$with_expired = $expired->groupBy('client_id');
/*counts the number of clients with expired policies instead of
*counting the number of expired policies first then checking
*against a list of 'client_id's
*/
$total_with_expired = $with_expired->count();

仍然存在确保"client_id"与客户表中的"id"真正匹配的问题。

最新更新