根据以下消息表,其中频道是特定聊天会话,user1
和user2
是聊天中的用户:
+---------+-------+-------+------------+
| channel | user1 | user2 | message |
+---------+-------+-------+------------+
| 5 | 15 | 8 | Hello |
| 5 | 15 | 8 | I'm John |
| 5 | 8 | 15 | Hi John |
| 6 | 9 | 15 | yo |
| 6 | 15 | 9 | heyo |
| 6 | 9 | 15 | you here? |
| 8 | 15 | 10 | Hi |
| 8 | 15 | 10 | you there? |
+---------+-------+-------+------------+
我想按channel
进行分组并选择第一个响应行(第二个人说的第一行)。如果第二个人从未在通道8中响应,则他们不需要显示在输出中。
所以我的预期输出是这样的:
+---------+-------+-------+---------+
| channel | user1 | user2 | message |
+---------+-------+-------+---------+
| 5 | 8 | 15 | Hi John |
| 6 | 15 | 9 | heyo |
+---------+-------+-------+---------+
请注意,有一个时间戳列,只是忘了包含它。任何帮助将不胜感激,一直在寻找一个尚未提出任何解决方案。感谢。
答案 0 :(得分:1)
自己并不完全相信。随意改进。 限制1依赖于每次从上到下读取的表。 而且我怀疑所有不同的选择都可以更优雅地完成。 但至少它为样本数据提供了所需的结果:)
SELECT channelchat.channel,
(SELECT user2
FROM chat firstline
WHERE firstline.channel = channelchat.channel
LIMIT 1) seconduser,
(SELECT user1
FROM chat firstline
WHERE firstline.channel = channelchat.channel
LIMIT 1) firstuser,
(SELECT message
FROM chat secondline
WHERE secondline.channel = channelchat.channel
AND secondline.user1 = seconduser
LIMIT 1) response
FROM chat channelchat
GROUP BY channelchat.channel
HAVING response IS NOT NULL
答案 1 :(得分:1)
假设您有一个时间戳列,您可以将第一条消息的user2
作为:
select m.*
from messages m
where not exists (select 1
from messages m2
where m2.channel = m.channel and
m2.timestamp < m.timestamp
);
所以,如果你想要第一条消息,你可以使用group_concat()
/ substring_index()`技巧:
select m.channel, m.user1, m.user2,
substring_index(group_concat(m2.messages order by m2.timestemp separator '|'), '|', 1)
from messages m join
(select m.*
from messages m
where not exists (select 1
from messages m2
where m2.channel = m.channel and
m2.timestamp < m.timestamp
)
) mfirst
on m.channel = mfirst.channel and
m.user1 = mfirst.user2
group by m.channel, m.user1, m.user2;