从加入中获取第一行

时间:2016-07-13 19:25:29

标签: mysql sql

我正在尝试在mysql请求上获得特殊行为。

以下是我的表格:

users
id, email

infos_users
id_user, firstName, lastName, avatar

chatroom
id

chatroomUsers
id_chatroom, id_user

chatMessage
id, id_chatroom, message, id_sender

我想要做的是根据用户ID获取每个房间的用户,以获得用户所在的每个聊天室。为此,我正在使用此请求:

SELECT     chatroomUsers.id_chatroom, 
           users.id, 
           infos_user.avatar, 
           infos_user.firstName, 
           infos_user.lastName  
FROM       chatroomUsers 
INNER JOIN users      ON chatroomUsers.id_user = users.id 
INNER JOIN infos_user ON infos_user.id_user = users.id 
WHERE      id_chatroom IN 
(
    SELECT id_chatroom 
    FROM   chatroomUsers 
    WHERE  id_user = ?
)

?是我关注的用户的ID。当然,我正在做一些后期处理来清理所有内容,并使用key = id_chatroom创建一个很好的数组,并为一组用户赋值。

接下来是什么?好吧,我想要每一行,聊天室的最后一条消息(具有相应id_chatroom和最高id_message值的消息)。目前请求将此返回给我:

id_chatroom     id   avatar      firstName  lastName
0               0    avatar1     blah1      blah2
0               1    avatar2     blah3      blah4
1               2    avatar3     blah5      blah6
1               1    avatar1     blah1      blah2
1               3    avatar4     blah7      blah8

我想要这样的事情:

id_chatroom     id   avatar      firstName  lastName    lastMessage         id_message  id_sender
0               0    avatar1     blah1      blah2       blahblahblah        0           1
0               1    avatar2     blah3      blah4       blahblahblah        0           1
1               2    avatar3     blah5      blah6       blahblahblahblah    1           3
1               1    avatar1     blah1      blah2       blahblahblahblah    1           3
1               3    avatar4     blah7      blah8       blahblahblahblah    1           3

再一次,为了做一些后期处理。但每当我试图构建我的请求时,它就会弄乱一切。

有人可以帮助我吗?

编辑:可能没有为聊天室记录消息!在这种情况下,我希望消息字段填充null

4 个答案:

答案 0 :(得分:0)

SELECT
   cru.id_chatroom, 
   u.id, 
   iu.avatar, 
   iu.firstName, 
   iu.lastName,
   cm.message AS lastMessage,
   xx.max_id AS id_message,
   cm.id_sender
FROM chatroomUsers cru
JOIN users u ON cru.id_user = u.id 
JOIN infos_user iu ON iu.id_user = u.id 
LEFT JOIN (
    SELECT
        MAX(cmx.id) AS max_id,
        cmx.id_chatroom
    FROM chatroomUsers cmx
    GROUP BY id_chatroom
) xx ON xx.id_chatroom = cru.id_chatroom
LEFT JOIN chatroomUsers cm ON (cm.id = xx.id)
WHERE      id_chatroom IN 
(chatroomUsers
    SELECT id_chatroom 
    FROM   chatroomUsers 
    WHERE  id_user = ?
);

在这里,您将加入一个具有每个聊天室的最后一个ID(MAX(id))的子选择。然后你再次加入以获取该消息的内容。

我使用了左连接,因为我不确定你的数据模型。我认为用户可能在一个房间,但房间可能是全新的,还没有说明。左连接确保您可以在这种情况下显示其余的用户信息。

警告lector:我没有方便的MySQL来测试它。

答案 1 :(得分:0)

我会为此使用某种日期戳列,但您可以使用自动增量ID来执行此操作。

(SELECT id_chatroom, message FROM chatMessage INNER JOIN (SELECT id_chatroom, max(id) AS most_recent_id FROM chatMessage GROUP BY id_chatroom) mostRecents ON chatMessage.id = mostRecents.most_recent_id)

如果将构造的表放入连接中,它应该可以工作。这种东西总是让人感觉很糟糕,但我从来没有找到更好的方法来订购和然后 GROUP。

答案 2 :(得分:0)

如果你想要一个聊天室的最后一条消息,你应该使用一个子查询;如果你想填充每个聊天室没有null值消息的消息列,你必须使用left join,所以我们可以这样做(可能很简单):

SELECT     chatroomUsers.id_chatroom, 
           users.id, 
           infos_user.avatar, 
           infos_user.firstName, 
           infos_user.lastName,
           sub.message AS lastMessage,
           sub.id AS id_message,
           sub.id_sender
FROM       chatroomUsers 
INNER JOIN users      ON chatroomUsers.id_user = users.id 
INNER JOIN infos_user ON infos_user.id_user = users.id
LEFT JOIN  (
    SELECT t1.*
    FROM chatMessage t1
    INNER JOIN (
        SELECT MAX(id) AS id, id_chatroom
        FROM chatMessage
        GROUP BY id_chatroom
    ) t2 ON t1.id_chatroom = t2.id_chatroom AND t1.id = t2.id
) sub                  ON chatroomUsers.id_chatroom = sub.id_chatroom 
WHERE      id_chatroom IN 
(
    SELECT id_chatroom 
    FROM   chatroomUsers 
    WHERE  id_user = ?
)

答案 3 :(得分:-1)

您想使用SELECT TOP子句。

所以

SELECT TOP 1  chatroomUsers.id_chatroom, 
       users.id, 
       infos_user.avatar, 
       infos_user.firstName, 
       infos_user.lastName