【问题标题】:SQL Server 2008 find the prior to last timestamp recordSQL Server 2008 找到最后一个时间戳记录
【发布时间】:2020-01-01 12:03:00
【问题描述】:

我正在尝试查询表以查找上一条记录。目前我已经尝试了各种解决方案,例如此代码,但我无法使其工作(见下文)

我要查询的字段来自此表[CMI_Industry_Workload].[dbo].[Gantt_Value],分别是[ProjectName][TimeStamp]

第一个字段是字符串字段,第二个字段是时间戳字段。

select t.*
from  (Select t.*
              row_number() over (partition by [ProjectName] order by [Timestamp]) as seqnum,
              count(*) over (partition by [ProjectName]) as cnt
       from [CMI_Industry_Workload].[dbo].[Gantt_Value] t
      ) t
where seqnum in (1, cnt - 1, cnt);

所以我希望得到的不是最近的记录,而是之前的记录。

非常感谢

加里

【问题讨论】:

  • SQL Server 2008 MySQL Server 2008。事实上没有 MySQL Server 2008 这样的东西。而且,你的查询肯定来自 SQL Server。
  • 是的,对不起,我搞混了
  • “上次记录之前”是指倒数第二个吗?如果是这样,升序中的倒数第二行是降序中的 2nd 行。看来你知道如何使用ROW_NUMBER,所以你应该能够在那里找到你需要的东西。

标签: sql-server timestamp


【解决方案1】:

这应该在表中的最后一条记录之前找到(假设数据按Timestamp 字段排序。这将按Timestamp 对行进行降序排序,跳过(偏移)1(最后一行)并仅获取一排,在最后一排之前。

SELECT T.*
FROM [CMI_Industry_Workload].[dbo].[Gantt_Value] AS T
ORDER BY [Timestamp] DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;

以上内容适用于 2012+

这是ROW_NUMBER的版本

SELECT *
FROM (  SELECT *, ROW_NUMBER() OVER (ORDER BY [Timestamp] DESC) AS Seq
        FROM [CMI_Industry_Workload].[dbo].[Gantt_Value]) AS T
WHERE T.Seq = 2;

这将再次按Timestamp desc 排序,并将选择第二个值(在最后一个之前)。

请记住,MSSQL 2008 已(或即将)不支持。我强烈建议升级。

更新

根据 OP 的评论,这肯定是答案:

SELECT *
FROM (  SELECT *, ROW_NUMBER() OVER (PARTITION BY [ProjectName] ORDER BY [Timestamp] DESC) AS Seq
        FROM [CMI_Industry_Workload].[dbo].[Gantt_Value]) AS T
WHERE T.Seq > 1;

第二次更新

如果Timestamp 值恰好是重复的,并且您希望将它们视为相同,您可能希望使用DENSE_RANK() 而不是ROW_NUMBER()。如果当前值与序列中的先前值匹配,它将分配相同的序列号。

SELECT *
FROM (  SELECT *, DENSE_RANK() OVER (PARTITION BY [ProjectName] ORDER BY [Timestamp] DESC) AS Seq
        FROM [CMI_Industry_Workload].[dbo].[Gantt_Value]) AS T
WHERE T.Seq > 1;

【讨论】:

  • 除非我记错了,OFFSETFETCH 在 SQL Server 2008 中不存在;但是,它在每个支持版本的 SQL Server 中都可用。
  • 是的,我只是自己想通了...不是问题:) 我会更新我的答案。
  • 这很有效,但只返回一条记录,我想要的是调用所有匹配 TimeStamp 和 ProjectRef 的记录,但不是最新的,而是之前的记录。
  • 现在我找到了一种方法来返回每个项目的所有唯一时间戳,现在我需要找到一种方法来只选择每个项目的最后一条记录:SELECT DISTINCT Timestamp as timing , Convert (VARCHAR(MAX),ProjectRef) as Project FROM [CMI_Industry_Workload].[dbo].[Gantt_Value] ORDER by timing DESC
  • @user2073602 更新了我的答案。这将根据Timestamp 顺序为每个ProjectName 生成1,2,3... 序列。然后,您需要做的就是恢复所有 Seq 不是 1 的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
相关资源
最近更新 更多