TSQL 时间戳和日期时间的排名

3

我正在尝试对一系列的交易进行排序,然而我的源数据没有记录一天中发生多次的交易时间,我唯一能使用的字段是timestamp字段 - 这样排名是否正确?

以下是代码:

SELECT [LT].[StockCode]
     , [LT].[Warehouse]
     , [LT].[Lot]
     , [LT].[Bin]
     , [LT].[TrnDate]
     , [LT].[TrnQuantity]
     , [LT].[TimeStamp] 
     , LotRanking = Rank() Over (Partition By [LT].[Warehouse],[LT].[StockCode],[LT].[Lot] Order By [LT].[TrnDate] Desc, [LT].[TimeStamp] Desc)
     From [LotTransactions] [LT]

以下是返回的结果:
StockCode   |Warehouse  |Lot    |Bin    |TrnDate                    |TrnQuantity    |TimeStamp          |LotRanking
2090        |CB         |3036   |CB     |2016-02-16 00:00:00.000    |2.000000       |0x0000000000500AB9 |1
2090        |CB         |3036   |CB     |2016-02-16 00:00:00.000    |2.000000       |0x0000000000500A4E |2
2个回答

3
首先,您应该使用rowversion而不是timestamp来跟踪行版本信息。我相信timestamp已经过时了。至少,文档明确建议使用[rowversion][1]
其次,我强烈建议您向表中添加一个标识列。这将提供您真正需要的信息,以及一个漂亮的唯一键。
通常,timestamprowversion仅用于确定行是否已更改,而不是确定排序。但是,根据此描述,您正在做的可能是正确的:
每个数据库都有一个计数器,该计数器针对包含数据库中的时间戳列的表上执行的每个插入或更新操作进行递增。此计数器是数据库时间戳。这在数据库中跟踪相对时间,而不是可以与时钟相关联的实际时间。表只能具有一个时间戳列。每次修改或插入带有时间戳列的行时,都会在时间戳列中插入递增的数据库时间戳值。
我要警告的是,这可能不安全。相反,它提供了为什么采用这种方法可能是有道理的原因。让我重申建议:添加标识列,以便您至少在未来正确地添加此信息。

很遗憾,我无法更改源数据表,因为这超出了我的权限范围,否则您的建议将是理想的。 - Chris J

2
您可以使用以下方法获取交易日期时间:datetime
SELECT LEFT(CONVERT(nvarchar(50),[LT].[TrnDate],121),10) + RIGHT(CONVERT(nvarchar(50),CAST([LT].[TimeStamp] as datetime),121),13)

对于第一个字符串,它将是:

2016-02-16 04:51:25.417

并使用这个进行排名。


我理解了答案,但点赞有些奇怪。原帖作者已经非常明确地说明日期列上没有时间组件。 - Gordon Linoff
TrnDate 上没有,但是从 TimeStamp 列中选择 SELECT CAST(0x0000000000500AB9 as datetime) 就会得到 1900-01-01 04:51:25.417 - gofr1
我应该补充说明,在SQL Server中将timestamp/rowversion视为实际日期、时间或日期时间值是明确的不好的想法。这些赞来自哪里? - Gordon Linoff
1
我能知道它们是从谁那里来的吗?是的,这是一个不好的想法,但正如 OP 评论所述,“我无法更改源数据表,因为这超出了我的权限”,所以他必须使用手头的资源。 - gofr1
1
@gofr1 谢谢你提供这个数据集,虽然它远远不是一个理想的数据集,但这确实为我提供了一些可以用来添加排名级别以显示数据的东西,并且知道它只有当天的准确性。 - Chris J
@ChrisJ . . . 从你最初的询问角度来看,这只是一种过于复杂化的方式。使用你最初的配方中的两个键更简单,且功能等效。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接