2016-01-26 4 views
1
id| from | to  |message |datetime    | 
---| ---------|---------|----------|---------------------| 
1 | john  | peter |Hi  |2016-01-01 12:00:00 | 
2 | peter | john |What's up |2016-01-01 12:01:00 | 
3 | jack  | jason |Hey  |2016-01-02 12:00:00 | 
4 | jason | jack |Hi  |2016-01-01 12:01:00 | 

Предположим, у меня есть таблица вроде этого, можете ли вы, ребята, дать мне представление о том, как написать запрос SQL Server, чтобы выбрать только последнее сообщение между двумя пользователями.SQL Server запрос SELECT только последнее сообщение

Ожидаемый результат для приведенного выше таблицы следует выбрать только идентификатор 2 и 3

+0

Для Ясон и домкратом, он должен быть 'идентификатор = 3'. –

+0

@FelixPamittan Нет, я хочу только последнее сообщение, id = 4 - это сообщение с последним дат-временем. – JK9

+0

Да, но 2016-01-02> 2016-01-01. Если это не опечатка. –

ответ

1

Применение ROW_NUMBER:

WITH Cte AS(
    SELECT *, 
     rn = ROW_NUMBER() OVER(
          PARTITION BY 
           CASE 
            WHEN [from] >= [to] THEN [from] 
            ELSE [to] 
           END, 
           CASE 
            WHEN [from] >= [to] THEN [to] 
            ELSE [from] 
           END 
          ORDER BY datetime DESC 
         ) 
    FROM tbl 
) 
SELECT * FROM CTE 
WHERE rn = 1 
ORDER BY id 

Для достижения надлежащей группировки, я организовать PARTITION BY по алфавиту, а это означает, что первый столбец в PARTITION будет первым из from и to в алфавитном порядке, а второй столбец будет последним.

Try it here.

+0

Является ли это хранимой процедурой? – JK9

+1

Это не хранимая процедура. Это запрос, который использует общие выражения таблиц и аналитические функции. –

1

Вот ANSI-92 совместимый решение, если вы не хотите использовать решение Феликса (который использует SQL Server ROW_NUMBER):

SELECT m1.* 
FROM messages m1 
INNER JOIN 
(
    SELECT t.v1 AS from, t.v2 AS to, MAX(t.datetime) AS maxTime 
    FROM 
    (
     SELECT CASE WHEN from < to THEN from ELSE to END AS v1, 
       CASE WHEN from < to THEN to ELSE from END AS v2, 
       datetime 
     FROM messages 
    ) t 
    GROUP BY t.v1, t.v2 
) m2 
ON ((m1.from = m2.from AND m1.to = m2.to) OR (m1.from = m2.to AND m1.to = m2.from)) 
    AND m1.datetime = m2.maxTime 
+0

Концепция здесь похожа на ответ @ Феликса Памиттана вправо? – JK9

+0

Трюк для обработки двухсторонних разговоров как один и тот же. План выполнения немного отличается. –

+1

OMG, это работает! большое спасибо – JK9

Смежные вопросы