代码之家  ›  专栏  ›  技术社区  ›  Joyner

如何避免laravel(php)中的嵌套查询?

  •  3
  • Joyner  · 技术社区  · 6 年前

    这里有两张桌子。我想使用优化的代码从这些表中检索数据。

    桌子:

    game_sessions
    Id, SessionName, StartTime
    
    games
    Id, GamesSessionId, GameName
    

    代码A:

    $sessions = DB :: select('select Id as sessionId, SessionName from game_sessions');
    foreach($sessions as $session)
    {
        $games = DB :: select('select Id as GameId, GameName from games where games.GameSessionId = '.$session->sessionId);  
        $session->Games = array();
        $session->Games = $games;
    }
    return array('status'=>true, 'session'=>$sessions);
    

    输出:($个会话)

    {
        "status": true,
        "session": 
        [
            {
                "sessionId": 1,
                "SessionName": "Regular bingo Manual",
                "Games": [
                    {
                        "GameId": 1,
                        "GameName": "Game1"
                    }
                ]
            },
            {
                "sessionId": 2,
                "SessionName": "Regular Automatic",
                "Games": [
                    {
                        "GameId": 2,
                        "GameName": "Game2"
                    },
                    {
                        "GameId": 3,
                        "GameName": "Game1"
                    }
                ]
            },
            {
                "sessionId": 3,
                "SessionName": "RegularDoubleAction",
                "Games": [
                    {
                        "GameId": 4,
                        "GameName": "Game1"
                    }
                ]
            }
        ]
    }
    

    代码B:

    $sessions = DB :: select('select game_sessions.Id as sessionId, SessionName, games.Id as GameId, games.GameName from game_sessions
                join games on games.GameSessionId = game_sessions.Id');
    return array('status'=>true, 'session'=>$sessions);
    

    输出:($个会话)

    {
        "status": true,
        "session": 
        [
            {
                "sessionId": 1,
                "SessionName": "Regular bingo Manual",
                "GameId": 1,
                "GameName": "Game1"
            },
            {
                "sessionId": 2,
                "SessionName": "Regular Automatic",
                "GameId": 2,
                "GameName": "Game2"
            },
            {
                "sessionId": 2,
                "SessionName": "Regular Automatic",
                "GameId": 3,
                "GameName": "Game1"
            },
            {
                "sessionId": 3,
                "SessionName": "RegularDoubleAction",
                "GameId": 4,
                "GameName": "Game1"
            }
        ]
    }
    

    这里我使用两种类型的代码。 在代码A中,我使用嵌套查询,但我将按会话分组获得输出。 在代码B中,我没有使用嵌套查询(通过使用联接避免嵌套查询),但我没有按会话分组获得输出。

    我需要的是我不想使用嵌套查询,但我希望我的输出按会话分组。 我怎样才能做到这一点?

    1 回复  |  直到 6 年前
        1
  •  2
  •   H H    6 年前

    您需要创建具有关系的模型

    https://laravel.com/docs/5.6/eloquent

    https://laravel.com/docs/5.6/eloquent-relationships

    创建 GameSession 具有以下关系的模型:

    function games() {
        return $this->hasMany(Game::class, 'GamesSessionId', 'Id');
    }
    

    在上创建反向关系 Game 型号:

    function session () {
        return $this->belongsTo(GameSession::class)
    }
    

    这将允许您获得 游戏会话 及其 游戏 s

    第一种方法是通过快速加载

    https://laravel.com/docs/5.6/eloquent-relationships#eager-loading

    $gameSessionWithGames = GameSession::with('games')->find($gameSessionId);
    

    这将为您提供 游戏会话 所有这些 游戏 s作为集合的属性

    或者直接通过关系:

    $gamesForSession = GameSession::find(gameSessionId)->games;
    

    这将返回所有 游戏 属于 游戏会话

    --

    以上两种方法都将返回一个集合,然后您可以 map

    https://laravel.com/docs/5.6/collections#method-map

    只获得所需的结果

    或通过添加 ->select('...', '..', '.') 到查询生成器

    https://laravel.com/docs/5.6/queries#selects