如何结合sql select查询这种情况?

时间:2011-07-24 21:08:36

标签: mysql select

我正在用php / mysql编写聊天应用

我有3个表:user, roomroom_participant这些结构:

user: id, username
room: id, title
room_participant: room_id, user_id

现在我想获得所有房间的清单以及每个房间中所有参与者的清单。

到目前为止,我只是从房间表中选择所有房间并遍历所有房间并从每个条目中选择用户信息,这是非常低效的。

有没有办法将所有这些选择组合成只有一个选择查询?

2 个答案:

答案 0 :(得分:2)

未经测试不确定,但试一试:

SELECT
   room.*, 
   user.* 
FROM room 
  JOIN room_participant ON room_id = room_participant.id
  JOIN user ON room_participant.user_id = user.id
ORDER BY room.id

要对房间进行重复数据删除,请使用GROUP_CONCAT()

修改

更新 GROUP_CONCAT()以返回id|username

SELECT
   room.id, room.name
   GROUP_CONCAT(CONCAT(user.id,'|',user.username)) AS userlist 
FROM room 
  JOIN room_participant ON room_id = room_participant.id
  JOIN user ON room_participant.user_id = user.id
GROUP BY room.id, room.name
ORDER BY room.id

userlist生成的GROUP_CONCATid|name,id|name,id|name,您可以使用PHP explode()分隔它们。

// Split the list on the commas
$users = explode(",", $userlist);


$final_users = array();
// Then split each on the `|`
foreach ($users as $user) {
  $split_user = explode("|", $user);

  // Append each as a new associative array to $final_users
  $final_users[] = array('id' => $split_user[0], 'username' => $split_user[1]);
}

// Now you have an array of users as id, username
var_dump($final_users);

答案 1 :(得分:0)

您可能希望执行两个查询,然后在使用MySQL的任何内容中进行匹配,例如: PHP。

这两个:

SELECT id, title
  FROM room;

SELECT rp.room_id, rp.user_id, u.username
  FROM room_participant AS rp
       INNER JOIN user as u ON rp.user_id = u.id;

或者这两个:

SELECT id, username
  FROM user;

SELECT rp.room_id, rp.user_id, r.title
  FROM room_participant AS rp
       INNER JOIN room as r ON rp.user_id = r.id;

哪两个查询有意义取决于您对信息的处理方式。

您可以更进一步,分别选择所有三个:

SELECT *
  FROM room;

SELECT *
  FROM user;

SELECT *
  FROM room_participant;

注意:最好先说明列,而不是使用'*',以防将来新列添加到您对这些查询不感兴趣的表中。

显然,你必须在任何使用MySQL的东西中匹配所有内容,例如: PHP。您可以从所选信息中创建房间和用户列表,然后将其与以下内容进行匹配:

// Use MySQL to populate $roomList from database, then do...
foreach ($roomList as $room)
{
    $id    = $room['id'];
    $title = $room['title'];

    $this->roomList[$id] = new Room($id, $title);
}

// Use MySQL to populate $userList from database, then do...
foreach ($userList as $user)
{
    $id       = $user['id'];
    $username = $user['username'];

    $this->userList[$id] = new User($id, $username);
}

// Use MySQL to populate $roomParticipantList from database, then do...
foreach ($roomParticipantList as $roomParticipant)
{
    $room = $this->roomList[$roomParticipant['room_id']];
    $user = $this->userList[$roomParticipant['user_id']];

    // You could do one/both of these, depending on requirements.
    $room->enterUser($user);
    $user->joinRoom($room);
}