[英]Laravel eloquent group by hasMany relationship
我有users
和user_positions
表。
用戶模型
public function positions()
{
return $this->hasMany(UserPosition::class);
}
示例數據:
用戶:
----------------
| id | name |
----------------
| 1 | Alex |
| 2 | Nick |
| 3 | John |
| 4 | Liam |
| 5 | Noah |
| 6 | William |
| 7 | James |
| 8 | Oliver |
| 9 | Benjamin|
| 10 | Elijah |
| 11 | Lucas |
----------------
用戶職位
------------------------
| position | user_id |
------------------------
| Developer | 1 |
| Designer | 2 |
| Teacher | 1 |
| Singer | 3 |
| Architect | 3 |
| Accountant | 4 |
| Baker | 2 |
| Actress | 7 |
| Chef | 11 |
| Butcher | 10 |
| Carpenter | 8 |
| Developer | 9 |
| Accountant | 11 |
| Butcher | 8 |
| Singer | 10 |
| Carpenter | 7 |
| Carpenter | 1 |
------------------------
在這種情況下,我如何按職位名稱對用戶進行分組並獲得如下結果:
[
Developer => [1, 9],
Designer => [2],
Teacher => [1],
Singer => [3, 10],
Architect => [3],
Accountant => [4, 11],
Baker => [2],
Actress => [7],
Chef => [11],
Butcher => [10, 8],
Carpenter => [8, 7, 1]
]
您可以使用GROUP_CONCAT進行相同的操作:
$data = UsersPosition::selectRaw("position, GROUP_CONCAT('user_id')")
->groupBy('position')
->get();
https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat
嘗試這個:
$data = UsersPosition::selectRaw("position, GROUP_CONCAT('user_id')")
->groupBy('position')
->get();
由於 mysql 無法為您提供關聯數組,因此您應該使用GROUP_CONCAT
函數。 如果您有用戶,例如$user = Auth::user()
並且您獲得$user->positions
您將獲得一個用戶的所有職位。
如果您想獲得每個位置的分組數據,您應該運行以下代碼:
UserPosition::query()
->selectRaw('
position,
GROUP_CONCAT(user_id) as users
')
->groupBy('user_id')
->get()
->map(function($val){
$val->users = explode(',', $val->users);
})
->pluck('users', 'position')
->toArray();
你會得到你想要的數組
您正在尋找多對多關系。 如果您按照Laravel 文檔使用中間數據透視表,您可以輕松地反轉查找。
現在你有用戶有很多位置,但你沒有結構可以輕松地將所有用戶放在某個位置,因為位置在你的輔助表中重復。
如果您使用中間表,您可以讓用戶擁有職位,職位擁有為您提供分組的用戶,並且還可以減少職位名稱的數據重復。
我喜歡 Sehdev 的回答,但要獲得所需的密鑰,您可以嘗試對生成的 Eloquent\\Collection 進行操作。
UserPosition::where(...)->get()
->groupBy('position')->map(function (array $groupedPositions) {
return collect($groupedPositions)->pluck('id');
});
這有點不同,因為一旦您調用get()
,您就在與 Collection 對象對話,而不是 Query\\Builder 對象。 這意味着隨后的groupBy()
調用是不一樣的一個否則會過濾出查詢結果,而是其嵌套。 這使map()
方法可以訪問以您描述的方式組織它所需的所有數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.