查询具有一对多关系的数据库

时间:2019-04-09 23:36:48

标签: php sql

我正在建立一个数据库,当用户注册时,他们会选择3种他们想玩的游戏。游戏与用户信息表(个人信息)存储在单独的表(gameinfo)中。我正在查询显示的第一个游戏,但我希望为每个用户显示所有三个。我将如何实施显示所有游戏的游戏?

我试图为每个游戏创建不同的变量,但是这似乎并没有按我预期的那样工作并失败了。当游戏存储在个人信息表中时,它们会以数字1或2的形式存储。这些链接到gameinfo表,并且是每个游戏的主键。

数据库结构
https://imgur.com/a/qee9C1t

    $conn = mysqli_connect('localhost', 'root', '', 'esportclub');
    $sql = "SELECT user_ID, username, Email, Gender, firstName, lastName, gameName FROM personalinformation, gameinfo WHERE game_id = firstGame";
    $result = mysqli_query ($conn, $sql);


    if (mysqli_num_rows($result) > 0) {
      echo "<table>";

      while($row = mysqli_fetch_assoc($result)) {
        echo " <tr><td> Name: ". $row{"username"}. " </td><td> Email: ". $row{"Email"}.  " </td><td> Gender: ". $row{"Gender"}. "</td>" .
          "<td> First Name: ". $row{"firstName"}. " </td><td> First Game: ". $row{"gameName"}. "</td><td> Last Name: ". $row{"lastName"}. "</td>" . "</td></tr>" ;
      }
      echo "</table>";
    } 
    else{
      echo "0 results";
    }
    $conn->close();

1 个答案:

答案 0 :(得分:1)

如我的评论中所述,我将通过存储user_IDgame_id的唯一值对来创建一个表来关联用户和游戏。然后,我将表相应地联接在一起。

但是,我看到您在personalinformation表中的firstGamesecondGamethirdGame列中为每个用户存储了三个游戏值。

在这种情况下,您可以将游戏表加入其中的每一列。
因此,使用您现有的结构:

SELECT
    p.*,
    game1.`gameName` as `firstGame_name`,
    game2.`gameName` as `secondGame_name`,
    game3.`gameName` as `thirdGame_name`
FROM `personalinformation` p
LEFT JOIN `games` as game1 ON (game1.`game_id` = p.`firstGame`)
LEFT JOIN `games` as game2 ON (game2.`game_id` = p.`secondGame`)
LEFT JOIN `games` as game3 ON (game3.`game_id` = p.`thirdGame`)
WHERE 1; // or WHERE p.`user_ID` = :user_ID;

编辑

由于许多用户可以拥有一个游戏,而一个用户可以拥有许多游戏,因此听起来像是“多对多”关系。

对于这种类型的关系,这是我的首选方法。优势之一是您无需限制分配的游戏数量。也就是说,用户可以拥有任意数量的游戏。

创建第三个表来存储唯一的用户/游戏对。
它将告诉您哪些游戏分配给了哪些用户。
像这样:

CREATE TABLE `user_game` (
  `user_id` MEDIUMINT NOT NULL ,
  `game_id` MEDIUMINT NOT NULL
);
ALTER TABLE `user_game`
  ADD UNIQUE `unique pair` (`user_id`, `game_id`);

然后将三个表连接在一起:

SELECT
    u.*,
    g.`game_id`,
    g.`gameName`
FROM `personalinformation` u
LEFT JOIN `user_game` as ug ON ( ug.`user_id` = u.`user_ID` )
LEFT JOIN `games` as g ON ( g.`game_id` = ug.`game_id` )
WHERE 1;

对于每个用户/游戏关系,您都会返回一行。
如果一个用户有3个游戏,则该用户将在结果中包含3行,每行包含一个gameName

例如:

Name   Game
----   -----------------
Jane   League of Legends
Jane   Minecraft
Fred   Dota 2
Alex   Minecraft
Alex   War Dragons
Alex   Fortnite

更复杂的显示可能需要一些处理:

<?php

$users = array();

while($row= mysqli_fetch_object($result)) {

    $uid = $row->user_ID;

    // if this user isn't in the array...
    if (!array_key_exists($uid,$users)) {

        // ... create a user entry ...
        $user = new stdClass();
        $user->firstname = $row->firstName;

        // ... and add it to the user array.
        $users[$uid] = $user;

    }

    // if this row has a valid game ...
    if (!empty($row->game_id)) {

        // ... create a game entry ...
        $game = new stdClass();
        $game->id = $row->game_id;
        $game->name = $row->gameName;

        //.. and add the game to the user's entry
        $users[$uid]->games[$game->id]=$game;

    }

}

对于这样的结构:

Array
(
    [1] => stdClass Object
        (
            [firstname] => Jane
            [games] => Array
                (
                    [1] => stdClass Object
                        (
                            [id] => 1
                            [name] => Leage of Legends
                        )

                    [2] => stdClass Object
                        (
                            [id] => 2
                            [name] => Minecraft
                        )

                )

        )

    [2] => stdClass Object
        (
            [firstname] => Fred
            [games] => Array
                (
                    [3] => stdClass Object
                        (
                            [id] => 3
                            [name] => Dota 2
                        )

                )

        )

    [3] => stdClass Object
        (
            [firstname] => Alex
            [games] => Array
                (
                    [2] => stdClass Object
                        (
                            [id] => 2
                            [name] => Minecraft
                        )

                    [4] => stdClass Object
                        (
                            [id] => 4
                            [name] => War Dragons
                        )

                    [5] => stdClass Object
                        (
                            [id] => 5
                            [name] => Fortnite
                        )

                )

        )

)