SQL:JOIN后的GROUP BY没有覆盖行?

时间:2012-10-19 14:37:16

标签: mysql sql join group-by

我有一张篮球联赛的桌子,一桌球队和一张像这样的球员桌子:

LEAGUES
ID   |   NAME    |
------------------
1    |   NBA     |
2    |   ABA     |

TEAMS:
ID   |   NAME    |  LEAGUE_ID
------------------------------
20   |   BULLS   |    1
21   |   KNICKS  |    2

PLAYERS:
ID   |   TEAM_ID  |  FIRST_NAME | LAST_NAME | 
---------------------------------------------
1    |      21    |   John      |  Starks   |    
2    |      21    |   Patrick   |  Ewing    |    

鉴于联盟ID,我想从联盟中的所有球队中检索所有球员的名字和他们的球队ID,所以我这样做:

SELECT t.id AS team_id, p.id AS player_id, p.first_name, p.last_name
FROM teams AS t
JOIN players AS p ON p.team_id = t.id
WHERE t.league_id =  1

返回:

[0] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 1
        [first_name] => John
        [last_name] => Starks
    )

[1] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 2
        [first_name] => Patrick
        [last_name] => Ewing
    )

+ around 500 more objects...

由于我将使用此结果填充每个团队的下拉菜单,其中包含每个团队的玩家列表,我想按团队ID对结果进行分组,因此创建这些下拉列表的循环只需循环每个团队ID而不是每次都是500多名玩家。

但是当我像这样使用GROUP BY时:

SELECT t.id AS team_id, p.id AS player_id, p.first_name, p.last_name
FROM teams AS t
JOIN players AS p ON p.team_id = t.id
WHERE t.league_id =  1
GROUP BY t.id

它只返回每个团队中的一个玩家,因为使用了相同的列名,所以覆盖了同一团队中的所有其他玩家。

[0] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 2
        [first_name] => Patrick
        [last_name] => Ewing
    )
[1] => stdClass Object
    (
        [team_id] => 22
        [player_id] => 31
        [first_name] => Shawn
        [last_name] => Kemp
    )
etc...

我想返回这样的内容:

[0] => stdClass Object
    (
        [team_id] => 2

        [player_id1] => 1
        [first_name1] => John
        [last_name1] => Starks
        [player_id2] => 2
        [first_name2] => Patrick
        [last_name2] => Ewing

        +10 more players from this team...
    )

    +25 more teams...

有可能吗?

2 个答案:

答案 0 :(得分:4)

您无法在SQL中执行此操作,因为您无法以数据集的形式表示该结果。你想要返回复杂的对象。你可以做的是在代码中处理这个问题,并通过返回一个按team_id排序的数据集来帮助自己。每当你的team_id改变时,就可以在代码中创建新对象并用新的播放器列表填充它。

它会是这样的(语法可能不正确):

返回结果集:

team_id|player_id|first|last
1|1|f1|l1
1|2|f2|l2
1|3|f3|l3
2|5|f5|l5
2|6|f6|l6

在代码中返回时

$lastTeamId=0;
$output=array();
foreach($results as $row){
  if($lastTeamId != $row["team_id"]){
    $lastTeamId = $row["team_id"];
    $output[$lastTeamId] = array();
  }

  $newPlayer = null;
  $newPlayer->id = $row["player_id"];
  $newPlayer->first = $row["first"];
  $newPlayer->last = $row["last"];
  $output[$lastTeamId][] = $newPlayer;
}

答案 1 :(得分:0)

在MySQL中,您可以GROUP BY team_id然后SELECT GROUP_CONCAT(玩家详细信息......)。但这会受到限制,而不是典型的关系方法。