2017-09-14 120 views
0

我试图在一行中获取与它关联的对话列表和与会者,以及给定用户的最后一条消息。我正在寻找的结果是这样的:SQL查询同一行中同一列的多个值

**| conversationId | participants | text | timestamp |** 
      67   aester,bester Hello 00:00:00 

上述模型只是一行。我正在试图获得具有上述结果的所有行。文本列是与该对话关联的最后一条消息。

这里是我的模型:

用户

userId|username| 
    87 aester 
    89 cester 
    96 bester 

对话

|conversationId| 
     67 
     68 

消息

| messageId | text | timestamp | conversation_id | user_id 
    41  Hello  00:00:00   67    87 
    42  Hey  00:00:00   68    89 

UserConversations

| id | conversation_id | user_id 
    3   67   87 
    4   67   96 
    5   68   89 

如何查询上述模型以获得期望的结果?

当前的更新:

SELECT conversations.`conversationId` as conversationId, 
GROUP_CONCAT(users.`username`) as participants FROM users 
LEFT JOIN user_conversations 
ON users.`userId` = user_conversations.`user_id` 
LEFT JOIN conversations 
ON user_conversations.`conversation_id` = 
conversations.`conversationId` 
WHERE EXISTS (SELECT * FROM user_conversations WHERE 
user_conversations.user_id = 87) 
GROUP BY conversations.`conversationId`; 

以上是生产这是我想要的只是我无法弄清楚如何让每行也是在最后的消息:

| conversationId | participants | 
     67   aester,bester 
     68    cester 
+1

检查[** GROUP_CONCAT()**](https://www.w3resource.com/mysql/aggregate-functions-and-grouping/aggregate-functions-and-grouping-group_concat.php) –

+0

我试图使用GROUP_CONCAT,但它返回同一行上的所有参与者,即使它们不属于对话 – samuscarella

+0

向我们显示数据库模式,样本数据,当前和预期输出。 \t请阅读[**如何提问**](http://stackoverflow.com/help/how-to-ask) \t \t这里是一个伟大的地方[** START **] (http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/)来了解如何提高您的问题质量并获得更好的答案。 \t [**如何创建最小,完整和可验证示例**](http://stackoverflow.com/help/mcve) –

回答

0

如果你想谈话的名单,然后首先我们先从UserConversations得到与会者的列表中为每个conversation_id

SELECT uc.`conversation_id`, 
     GROUP_CONCAT(u.`username`) as participants  
FROM UserConversations1 uc 
JOIN Users1 u 
    ON uc.`user_id`= u.`userId` 
GROUP BY `conversation_id` 
HAVING COUNT(IF(uc.`user_id` = 87, 1, NULL)) > 0; 
    -- This check if the user in on the conversation. 

然后,我们发现了什么是每个conversation_id

SELECT `conversation_id` , MAX(`messageId`) as `messageId` 
FROM Messages1 
GROUP BY `conversation_id`; 
0123的最后一条消息

然后我们一起都在一起:

SQL DEMO

SELECT conversation.`conversation_id`, 
     conversation.`participants`, 
     m.text, 
     m.timestamp 
FROM ( SELECT uc.`conversation_id`, 
       GROUP_CONCAT(u.`username`) as `participants`  
     FROM UserConversations1 uc 
     JOIN Users1 u 
      ON uc.`user_id`= u.`userId` 
     GROUP BY `conversation_id` 
     HAVING COUNT(IF(uc.`user_id` = 87, 1, NULL)) > 0) as conversation 
JOIN (SELECT `conversation_id` , MAX(`messageId`) as `messageId` 
     FROM Messages1 
     GROUP BY `conversation_id`) as last_message 
    ON conversation.`conversation_id` = last_message.`conversation_id` 
JOIN Messages1 m 
    ON m.`messageId` = last_message.`messageId`; 

输出

enter image description here

注:我来补充1表的名字,因为一些表已经上我做演示的平台,可以nt放下它。

+0

谢谢!它似乎在工作。 – samuscarella

0

如果我没有理解你的问题正确,你想用Messages表加入你现有的查询,这样你可以得到每个对话的最后一条消息。这可以像这样完成。

首先创建一个子查询来获得最后的消息对于每个对话是这样

select message_id as last_message_id, text as last_text, conversation_id, user_id, max(timestamp) from   
(select * from `Messages` 
order by conversation_id, timestamp desc)q 
group by conversation_id; 

现在使用conversation_id列作为连接条件与查询上述子查询。这将填充最后的消息对你的结果

你最终的查询看起来像这样

SELECT conversations.`conversationId` as conversationId, 
GROUP_CONCAT(users.`username`) as participants FROM users 
LEFT JOIN user_conversations 
ON users.`userId` = user_conversations.`user_id` 
LEFT JOIN conversations 
ON user_conversations.`conversation_id` = 
conversations.`conversationId` 
WHERE EXISTS (SELECT * FROM user_conversations WHERE 
user_conversations.user_id = 87) 
LEFT JOIN 
(select message_id as last_message_id, text as last_text, conversation_id, user_id, max(timestamp) from   
(select * from `Messages` 
order by conversation_id, timestamp desc)q 
group by conversation_id) subquery 
on conversations.`conversationId` = subquery.`conversation_id` 
GROUP BY conversations.`conversationId`; 
相关问题