0

我正在制作一个类似于 facebook 的聊天系统,您可以在其中同时与 2 或 3 人交谈。我的问题是关于选择对话。

inbox_conversation(此表用于在用户第一次开始交谈时创建新的会话 ID)

id_conversation | occured_at
       1           13482942
       2           18583953

inbox_join(用于用户加入会话的表,在这种情况下,用户 1、2、3 在 ID 为 1 的讨论中)

id_conversation | id_user
      1            1
      1            2
      1            3
      2            4
      2            5

inbox_msg(用于记录已发送消息的表)

id_conversation | id_user | message | occured_at
     1              1         Hey      1457694
     1              2         Hola     3848374 
     1              3         Cool     3294933
     2              4         Wow      4392934
     2              5         Yes      9485737

现在我必须做一些查询来选择只有对话的 id_user 的消息,在这种情况下我有 1、2、3。有人可以帮我建立这个查询。

我正在寻找选择与 id_user 1,2,3 讨论的最终结果

id_user | message | occured_at
 1         Hey       1457694
 2         Hola      3848374
 3         Cool      3294933

PS:如果对话有 3 个用户并且我尝试只选择其中 2 个,我将无法看到对话。

如果在这种情况下我只有用户 1,2 的 id,则没有与该 2 用户的讨论,但如果用户 1 写入数据库中的用户 2 将是另一个 id 讨论,并将与两个用户相关。像这样,如果我添加另一个用户示例用户 3,他将看不到用户 1 和 2 之间发送的先前消息

如果仅使用 id 用户选择是一个坏主意,我可以研究一些解决方案来传递讨论的 id。

4

2 回答 2

1

好的,我确实想出了一个叫做“数据集比较”的逻辑,其中多行的多个数据集被比较,需要查找它们中的任何一个是否匹配。

这个查询的基本点是,在搜索过程中,我们需要确保我们找到的会话在value 和 count上具有完全相同的用户。(仅此而已+仅此而已+相同的值)

    DECLARE @inbox_msg TABLE
    (
        id_conversation     INT NOT NULL
        ,id_user            INT NOT NULL
        ,[message]          NVARCHAR(MAX) NULL
        ,occured_at         TIMESTAMP NOT NULL
    )

    INSERT INTO @inbox_msg
            ( id_conversation ,
              id_user ,
              message
            )
                SELECT 1,1,'Hey'
    UNION ALL   SELECT 1,2,'Hola'
    UNION ALL   SELECT 1,3,'Cool'
    UNION ALL   SELECT 2,4,'Wow'
    UNION ALL   SELECT 2,5,'Yes'
    --this I added to make sure 3 will not become part of your result set.
    UNION ALL   SELECT 3,1,'Testing'
    UNION ALL   SELECT 3,2,'Search'
    UNION ALL   SELECT 3,3,'query'
    UNION ALL   SELECT 3,4,'Result'

    --this is the list of users you want to search for
    DECLARE @searchMessgeByUser TABLE
    (
        id_user INT NOT NULL PRIMARY KEY

    )
    INSERT INTO @searchMessgeByUser ( id_user )
    SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3


    --find out the sessionID who has exactly same number of user as participant as requested
    DECLARE @MatchedSessionID TABLE
    (
        id_conversation INT NOT NULL
    )
    INSERT INTO @MatchedSessionID( id_conversation )
    SELECT qry.id_conversation
    FROM
    (
        --find out the MatchedSessionIDByUserCount
        SELECT id_conversation
        FROM @inbox_msg
        GROUP BY id_conversation
        HAVING (COUNT(DISTINCT id_user) = (SELECT COUNT(1) FROM @searchMessgeByUser) )

        INTERSECT

        --find out the MatchedSessionIDByUserValue
        SELECT id_conversation
        FROM @inbox_msg msg
        JOIN @searchMessgeByUser usr
        ON msg.id_user=usr.id_user
        GROUP BY msg.id_conversation
    )qry


    --final Query
    SELECT id_user,message,occured_at
    FROM @inbox_msg
    WHERE id_conversation IN (SELECT id_conversation FROM @MatchedSessionID)
    ORDER BY occured_at
于 2013-10-01T22:46:10.897 回答
0

这些问题有点不清楚,所以只要弄清楚你到底需要什么?

在开始时,您提到仅根据 ID_User 查询结果。但是在最后一个示例中,您说“...结果是 DiscussionID 1”,那么哪个是正确的?DiscussionID 和 ID-User 是否都可用于过滤?

另外,“PS:如果对话有 3 个用户,而我尝试只选择其中 2 个,我将无法看到对话”

这是否意味着 id_User 过滤器的类型为“WHER ID_USER IN ('','','',)”

于 2013-10-01T21:14:23.683 回答