簡體   English   中英

Laravel eloquent group by hasMany 關系

[英]Laravel eloquent group by hasMany relationship

我有usersuser_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM