2016-06-07 91 views
3

我想排名一系列交易,但是我的源数据并没有捕获一天可能发生多次的交易时间,我唯一可以使用的其他字段是timestamp字段 - 这将排名是否正确?使用时间戳和日期时间的TSQL排名

下面的代码

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

您可以使用这样的事情来获得交易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 

并将其用于排名。

+0

我明白答案,但upvote很好奇。 OP很清楚地表明日期栏中没有时间分量。 –

+0

'TimeStamp'上没有'TrnDate',而是'SELECT CAST(0x0000000000500AB9 as datetime)'给出了这个:'1900-01-01 04:51:25.417'。 – gofr1

+0

我应该补充说,将'timestamp' /'rowversion'视为实际的日期,时间或日期时间值在SQL Server中显然是一个坏主意。 upvotes从哪里来? –

3

首先,您应该使用rowversion而不是timestamp来跟踪行版本信息。我相信timestamp已被弃用。至少,文件明确建议[rowversion][1]

其次,我强烈建议你在表中添加一个标识列。这将提供您真正需要的信息 - 以及表格的一个很好的唯一键。

通常,timestamprowversion仅用于确定行是否已更改 - 不确定排序。但是,在此基础上的描述,你在做什么可能是正确的:

每个数据库都有一个递增为包含内部的一个 时间戳列是对表执行的每个插入或 更新操作计数器数据库。该计数器是数据库 时间戳。这跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间。一个表格只能有一个时间戳列 。每当具有时间戳列的行为 修改或插入时,增加的数据库时间戳值将插入时间戳记列中的 。

我会提醒的是,这可能不安全。相反,它给出了这种方法可能有意义的原因。让我重复一下这个建议:添加一个标识列,以便您至少在将来能够正确添加此信息。

+0

不幸的是,我不能更改源数据表,因为这是超出我的范围,否则您的建议将是理想的 –