为每个唯一列值选择最后一项

时间:2018-09-17 13:09:48

标签: sql tsql

我有一个包含消息日志的表。每个对话都有一个对话ID。

我想选择不同的对话ID,然后为每个对话ID查找具有该对话ID的最新消息,并将其加入行中。

这是我尝试过的方法,但是除了两列(conversationIdid)之外,它没有向表中添加任何数据。我想从该表的每一行中获取具有最新

的所有列
SELECT 
  logs.conversationId, 
  -- latest message id
  MAX(logs.id) AS id
  FROM [dbo].[Logs] AS logs

  -- trying to get the remaining columns for the last message with that conversation ID
  LEFT JOIN [dbo].[Logs] AS logs2 ON logs.id = logs2.id

  WHERE 
    -- only conversations for last month
    logs.timestamp >= DATEADD(month, -1, GETDATE())

  GROUP BY logs.conversationId

当我尝试将另一列添加到SELECT时,出现错误消息,我需要将该列添加到GROUP BY子句中。但这导致该语句运行非常长的时间,结果仅几十行就需要20秒钟以上。

3 个答案:

答案 0 :(得分:1)

使用row_number()函数

select * 
from (
    select *, 
           row_number() over(partition by conversationId order by id desc) as rn 
    from logs 
) as t where t.rn=1

答案 1 :(得分:0)

首先从日志获取每次转换的最大日志ID,然后应用左连接:

select * from 
(SELECT 
  logs.conversationId, 
  MAX(logs.id) AS id
  FROM [dbo].[Logs] AS logs group by logs.conversationId)a
left join [dbo].[Logs] AS logs2 ON a.id = logs2.id and a.conversationid=logs.conversationid

答案 2 :(得分:0)

我会在where中使用子查询来实现它。

select * 
from logs t 
where t.id = (
    SELECT MAX(tt.id)
    from logs tt
    WHERE tt.conversationId = t.conversationId
    GROUP BY tt.conversationId
)

注意

如果您在id中建立索引可能比row_number版本更快