我有两个带有字段product_code的表杂志,还有另一个表问题.他们属于ToMany关系.
杂志型号:
public function issues()
{
return $this->hasMany('App\Issue');
}
问题模型:
public function magazine()
{
return $this->belongsTo('App\Magazine');
}
目前我有一个查询,其中我收到按杂志ID分组的问题集合,并按上一期的日期排序.
$issues = Issue::orderBy('date', 'desc')->get()->groupBy('magazine_id');
这是我的查询结果如下:
Collection {#431 ▼
#items: array:23 [▼
103 => Collection {#206 ▼
#items: array:52 [▶]
}
106 => Collection {#216 ▶}
124 => Collection {#452 ▶}
112 => Collection {#451 ▶}
115 => Collection {#450 ▶}
123 => Collection {#449 ▶}
107 => Collection {#448 ▶}
113 => Collection {#447 ▶}
117 => Collection {#446 ▶}
109 => Collection {#445 ▶}
110 => Collection {#444 ▶}
121 => Collection {#443 ▶}
120 => Collection {#442 ▶}
114 => Collection {#441 ▶}
116 => Collection {#440 ▶}
118 => Collection {#439 ▶}
126 => Collection {#438 ▶}
125 => Collection {#437 ▶}
119 => Collection {#436 ▶}
122 => Collection {#435 ▶}
105 => Collection {#434 ▶}
111 => Collection {#433 ▶}
104 => Collection {#432 ▶}
]
}
因此,由于我有24个杂志,阵列中有24个问题集,每个问题集属于一个杂志.集合按每个集合的最晚发布日期排序,每个集合内部的问题也按日期排序.因此,数组中的第一个集合将是表问题中具有最新问题的集合,第二个集合将是在同一个表中具有第二个最新问题的集合,依此类推.
由于我将获得一系列用户订阅,其中包含以下产品代码:
$productCodes = ['aa1', 'bb2', 'cc3'];
我需要扩展此查询并通过我将获得的$productCodes数组对集合进行进一步排序.我需要检查表格杂志中productCodes数组中的代码,其中包含product_code字段.按杂志分组的问题集应该进行排序,以便第一个集合是他们所属的杂志与阵列productCodes中的代码具有相同的product_code,其中第一个集合的集合是迄今为止的最新一期.然后其余的集合应该按日期排序.我怎样才能进行这种查询?
更新
我在@Paul Spiegel的答案中尝试了一个建议的代码,现在我得到了一系列的收藏品,杂志问题的集合.每个杂志集合中的问题按日期排序,与$productCodes数组中具有相同product_code的杂志集合位于数组的开头,但杂志集合的数组仍未按最新问题的日期排序来自每个杂志收藏.
解决方法:
首先:您可以只使用关系,而不是使用Collection :: groupBy():
$magazines = Magazine::with(['issues' => function($query) {
$query->orderBy('date', 'desc');
}]);
这将为您提供一系列杂志,包括阵列中的相关问题. issues数组按日期desc排序.
现在,您可以使用具有不同条件的两个查询来拆分结果:
$baseQuery = Magazine::with(['issues' => function($query) {
$query->orderBy('date', 'desc');
}]);
$query1 = clone $baseQuery;
$query2 = clone $baseQuery;
$query1->whereIn('product_code', $productCodes);
$query2->whereNotIn('product_code', $productCodes);
$query1将从数组中返回包含product_code的所有杂志. $query2将返回所有其他杂志.
您现在有两种方法可以将两种结果组合在一起:
1)使用Eloquent :: unionAll()
$unionQuery = $query1->unionAll($query2);
$magazines = $unionQuery->get();
2)使用Collection :: merge()
$magazines1 = $query1->get();
$magazines2 = $query2->get();
$magazines = $magazines1->merge($magazines2);
在这两种情况下,您都会得到相同的结果:一系列杂志.来自$productCodes数组的product_code的杂志首先排序.每个Magazine对象都包含与相关Issue对象的数组问题.
如果你想摆脱杂志对象并且真的需要在你的问题中看起来像你的结果,你仍然可以:
$issues = $magazines->keyBy('id')->pluck('issue');
但可能没有必要这样做.
更新
如果你真的需要杂志集合的两个部分按最新的问题排序..我没有看到任何方式没有使用JOIN或在PHP中使用闭包进行排序.使用连接对杂志进行排序也需要聚合.所以我会切换回原始查询,使用连接扩展它,并将其分为两部分,如上所示:
$baseQuery = Issue::join('magazines', 'magazines.id', '=', 'issues.magazine_id');
$baseQuery->orderBy('issues.date', 'desc');
$baseQuery->select('issues.*');
$query1 = clone $baseQuery;
$query2 = clone $baseQuery;
$query1->whereIn('magazines.product_code', $productCodes);
$query2->whereNotIn('magazines.product_code', $productCodes);
然后
$issues1 = $query1->get()->groupBy('magazine_id');
$issues2 = $query2->get()->groupBy('magazine_id');
$issues = $issues1->union($issues2);
要么
$issues = $query1->unionAll($query2)->get()->groupBy('optionGroupId');
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。