如何从“消息”表中选择聊天?

时间:2019-03-20 00:52:22

标签: sql sql-server

我有一个简单的消息表。

FROM|TO|DATETIME|MSG
----|--|--------|---
    |  |        |

给一个用户,我想选择聊天。例如:

FROM|TO|DATETIME|MSG
----|--|--------|---
 A  |B |    1   | x
 B  |A |    2   | x
 B  |A |    3   | x
 A  |B |    4   | x
 C  |A |    8   | x

我要选择A的聊天(A向其他用户发送或接收的最后一个聊天)。

FROM|TO|DATETIME|MSG
----|--|--------|---
 C  |A |    8   | x
 A  |B |    4   | x

这就是我所拥有的

create procedure GetMessageHeaders
    @user varchar(30)
as
    with msg as
    (
        select M.transmitter,M.receiver
        from "MESSAGE" M
        where M.receiver=@user or M.transmitter=@user
        order by M.DATE desc
    )
    select *
    from msg

2 个答案:

答案 0 :(得分:2)

我认为遵循这些思路的东西会起作用。您需要按时间顺序排列的每个分组的第一个实例。

    SELECT
        *
    FROM
    (
        SELECT
            *,
            LastInstanceReversed = ROW_NUMBER() OVER(PARTITION BY FROM,TO ORDER BY DATETIME DESC)
        FROM
            Message
    )AS X
    WHERE
        X.LastInstanceReversed=1

答案 1 :(得分:2)

可能有一种更简单的方法,但是以下方法可以产生所需的结果。我们首先生成一个开始的聊天记录和一个接收到的聊天记录的组合记录集,然后我们为“另一方”计算出一个行号,然后仅对另一方过滤出一行。

declare @Message table ([From] varchar(1), [To] varchar(1), [DateTime] int, msg varchar(1));

insert into @Message ([From], [To], [DateTime], msg)
  select 'A', 'B', 1, 'x'
  union all
  select 'B', 'A', 2, 'x'
  union all
  select 'B', 'A', 3, 'x'
  union all
  select 'A', 'B', 4, 'x'
  union all
  select 'C', 'A', 8, 'x'

select [From], [To], [DateTime], Msg
from (
  select *
    -- Calculate a row number per other party by time
    , row_number() over (partition by case when [Type] = 0 then [To] else [From] end order by [DateTime] desc) Row#
  from (
    -- Get chats we initiated
    select 0 [Type], [From], [To], [DateTime], Msg
    from @Message
    where [From] = 'A'
    union all
    -- Get chats we recevied
    select 1 [Type], [From], [To], [DateTime], Msg
    from @Message
    where [To] = 'A'
  ) X
) Y
where Row# = 1