首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >选择与我交谈过的用户,并与他们最后留言,比如whatsapp

选择与我交谈过的用户,并与他们最后留言,比如whatsapp
EN

Stack Overflow用户
提问于 2013-10-29 07:08:19
回答 2查看 2.4K关注 0票数 4

我的数据库里有张桌子:

sentBysentTo是FK到User表。

在这个表中,我在用户之间有消息:

代码语言:javascript
运行
复制
sentBy |  sentTo  |     dateSent     |     body
-------+----------+------------------+-----------------
  1    |    2     | 11/21/2010 10:00 | Hey!
-------+----------+------------------+-----------------
  2    |    1     | 11/21/2010 10:50 | Hi!
-------+----------+------------------+-----------------
  1    |    2     | 11/21/2010 10:51 | msg body 1
-------+----------+------------------+-----------------
  2    |    1     | 11/21/2010 11:05 | msg body 2
-------+----------+------------------+-----------------
  1    |    3     | 11/21/2010 11:51 | msg body 3
-------+----------+------------------+-----------------
  3    |    1     | 11/21/2010 12:05 | msg body 4
-------+----------+------------------+-----------------
  1    |    3     | 11/21/2010 12:16 | msg body 5
-------+----------+------------------+-----------------
  4    |    1     | 11/21/2010 12:25 | msg body 6
-------+----------+------------------+-----------------

我需要知道与用户1交谈过的用户以及与用户1交谈过的用户。在这种情况下,用户2、3和4(请注意,用户4已经向用户1发送了消息,但用户1尚未发送任何消息)。

第二个问题是:,我怎样才能得到每个用户的最后一条消息?,我要问的是如何将最新的消息发送给用户。

例如,如果我询问用户1,用户2的最新消息是: msg 2,而用户3的最新消息是msg 5。

如何在一个SELECT语句中获得该信息?或可能需要两个SELECT。

我试着做一些像WhatsApp这样的事情。这里有一个聊天屏幕,上面有我与之交谈过的用户列表(我的第一个问题),以及与他们交谈的最后一条信息(我的第二个问题)。

也许我可以创建另一个名为Conversation的表,将sentBysentTo移到该表中,并将发送给它的日期作为最后一条消息,但我认为这不是一个好的设计。

我的两个问题的结果是:

代码语言:javascript
运行
复制
sentBy |  sentTo  |     dateSent     |     body
-------+----------+------------------+-----------------
  2    |    1     | 11/21/2010 11:05 | msg body 2
-------+----------+------------------+-----------------
  1    |    3     | 11/21/2010 12:16 | msg body 5
-------+----------+------------------+-----------------
  4    |    1     | 11/21/2010 12:25 | msg body 6
-------+----------+------------------+-----------------
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-29 08:04:39

以下查询将为用户1提供预期的结果:

代码语言:javascript
运行
复制
select m.* from messages m
join (
  select auser,withuser,max(datesent) datesent from (
    select sentby as auser,sentto as withuser,datesent from messages 
    union
    select sentto as auser,sentby as withuser,datesent from messages 
    ) as ud
  group by auser,withuser
  ) maxud 
  on (m.datesent=maxud.datesent and maxud.auser in (m.sentBy,m.sentTo))
where auser=1

不用说,您可以更改where子句中的条件,以便为任何用户获得类似的结果。

但是,我的方法是创建一个视图,然后从视图中进行选择,如下所示:

代码语言:javascript
运行
复制
create view conversation_stuff as
select m.sentBy,m.sentTo,m.dateSent,m.body,maxud.auser,maxud.withuser
from messages m
join (
  select auser,withuser,max(datesent) datesent from (
    select sentby as auser,sentto as withuser,datesent from messages 
    union
    select sentto as auser,sentby as withuser,datesent from messages 
    ) as ud
  group by auser,withuser
  ) maxud 
  on (m.datesent=maxud.datesent and maxud.auser in (m.sentBy,m.sentTo))

select sentBy,sentTo,dateSent,body from conversation_stuff where auser=1;

我想这对其他用途也是有用的。

编辑:将user改为auser everywhere,以便sqlserver停止抱怨,并避免[]的.

票数 4
EN

Stack Overflow用户

发布于 2013-10-29 07:16:48

选择在dateSent上筛选的最大sentBy并按sentTo分组,然后将此结果加入到原始表中。

编辑:我看到问题了。您想要用户发送的收到的消息的最大消息吗?

代码语言:javascript
运行
复制
SELECT
    Messages.*
FROM
    Messages
    INNER JOIN
    (
        SELECT
            CombinedKey,
            MAX(dateSent) AS dateSent
        FROM
        (
            SELECT
                CombinedKey = CASE WHEN sentBy > sentTo
                    THEN CAST(sentBy AS nvarchar(10)) + '_' 
                        + CAST(sentTo AS nvarchar(10))
                    ELSE CAST(sentTo AS nvarchar(10)) + '_'
                        + CAST(sentBy AS nvarchar(10))
                    END,
                MAX(dateSent) AS dateSent
            FROM
                Messages
            WHERE
                sentBy = @user
                OR sentTo = @user
            GROUP BY
                sentBy,
                sentTo
        ) AS MaxMessagesBoth
        GROUP BY
            CombinedKey
    ) AS MaxMessages    
        ON MaxMessages.CombinedKey = CASE WHEN sentBy > sentTo
            THEN CAST(sentBy AS nvarchar(10)) + '_'
                + CAST(sentTo AS nvarchar(10))
            ELSE CAST(sentTo AS nvarchar(10)) + '_'
                + CAST(sentBy AS nvarchar(10))
            END
        AND MaxMessages.dateSent = Messages.dateSent
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19651811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档