Как выбрать чаты из таблицы сообщений? - PullRequest
0 голосов
/ 20 марта 2019

У меня есть простая таблица сообщений.

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 ]

2 голосов
/ 20 марта 2019

Там может быть более простой способ, но следующее дает желаемый результат.Сначала мы создаем объединенный набор записей чатов, которые мы начали, и чатов, которые мы получили, затем мы определяем номер строки для «другой» группы, а затем отфильтровываем только одну строку для каждой группы.

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
2 голосов
/ 20 марта 2019

Я думаю, что что-то в этом роде будет работать. Вам нужен первый экземпляр каждой группировки, упорядоченной в хронологическом порядке.

    SELECT
        *
    FROM
    (
        SELECT
            *,
            LastInstanceReversed = ROW_NUMBER() OVER(PARTITION BY FROM,TO ORDER BY DATETIME DESC)
        FROM
            Message
    )AS X
    WHERE
        X.LastInstanceReversed=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...