2010-03-07 91 views
9

我有一个表,我想跟踪时间间隔时间最好的方式,使一个有效的条目可能是:什么是存储在SQL Server数据库

  • 1小时3分钟
  • 47分钟
  • 10小时
  • 3分钟14秒

什么字段类型最适合用于此。我显然可以使用varchar。 。但我认为可能会有更好的事情,因为我想运行查询来总计大量的记录时间。

回答

12

不是使用字符类型来存储日期/时间信息。

在SQL Server 2008中,您有这种类型的time,如果您的时间间隔少于1天,应该使用这种类型。在以前的版本中,或者如果您需要存储较大的时间间隔,则必须使用datetimesmalldatetime(取决于您需要的精度)。

另一种选择是选择一个时间单位 - 比方说分钟数 - 并且只使用int值来表示单位数。只要确保(a)您选择的单位实际上足够精确,可以记录您需要跟踪的最小时间间隔;(b)实际数字类型足够大,可容纳您需要跟踪的最大时间间隔。 A smallint可能足以跟踪一天内的分钟数;另一方面,跟踪10年时间内的毫秒数将不得不存储为bigint

5

只需使用整数来存储以秒为单位的时间间隔。 DATEDIFF返回整数。编写一个将其转换为文本的函数。这其中需要一些adjustmens(所以它显示“1分钟”,而不是“1分钟”),但应该可以正常工作:

CREATE FUNCTION dbo.SecondsToText(@seconds int) 
RETURNS VARCHAR(100) 
AS 
BEGIN 
    declare @days int; 
    set @days = @seconds/(3600 * 24); 
    declare @hours int; 
    set @hours = (@seconds - @days * 3600 * 24)/3600; 
    declare @minutes int; 
    set @minutes = (@seconds - @days * 3600 * 24 - @hours * 3600)/60; 
    set @seconds = (@seconds - @days * 3600 * 24 - @hours * 3600 - @minutes * 60); 
    RETURN 
    RTRIM(CASE WHEN @days > 0 THEN CAST(@days as varchar) + ' days ' ELSE '' END + 
    CASE WHEN @hours > 0 THEN CAST(@hours as varchar) + ' hours ' ELSE '' END + 
    CASE WHEN @minutes > 0 THEN CAST(@minutes as varchar) + ' minutes ' ELSE '' END + 
    CASE WHEN @seconds > 0 THEN CAST(@seconds as varchar) + ' seconds ' ELSE '' END) 
END 
GO 
2

要看你的时间范围 - 要么一切转换成秒,只是存储的值作为INT,或者如果您的时间范围较大,则可能需要单独使用小时,分钟和秒的字段。

此外,SQL Server 2008引入了一个新的TIME data type,它允许您存储只有时间的值。

2

由于@Aaronaught表示使用日期/时间或日期时间(必要时)数据类型来存储您的值;但这些类型仅在时间上存储实例,而不是时间跨度或持续时间。您需要使用两个字段来存储间隔,例如[time_span_start]和[time_span_end]。两者之间的差异会给你的时间间隔。

通过下载Richard T. Snodgrass的“在SQL中开发面向时间的数据库应用程序”的副本,可以回答您的问题。它是免费提供的PDF,看看这里:

http://www.cs.arizona.edu/~rts/publications.html

0

相关托尼的回答,您还可以使用单相对于标准的开始时间,这是隐含的所有间隔日期时间列 - 例如: 1/1/1900 12:00 AM。

在这种情况下,它是很容易的存储:

INSERT INTO tbl (interval) VALUES (DATEADD(s, '1/1/1900', DATEDIFF(s, @starttime, @endtime)) 

现在,这显然不是容易做行的资金,所以你可以考虑增加持续DATEDIFF的计算列(S)(S, '1/1/1900',间隔)来提供执行SUM的秒数。现在

,这里就是它的SQL Server变得有趣:

因为SQL Server的实现将数字转换和从日期,0 - > 1/1/1900上午12:00,0.5 - > 1/1/1900 12:00 PM,1 - > 1/2/1900 12:00 AM等,即整个数字被视为自1/1/1900以来的天数,小数部分是一天内的分数。所以你可以天真地添加这些来获得间隔。

而事实上:

SELECT CONVERT(DATETIME, 1) + CONVERT(DATETIME, 0) + CONVERT(DATETIME, 2) + CONVERT(DATETIME, 0.5) 

给 '1900年1月4日12:00:00.000' 作为预期

这样你就可以做到这一点(通过转换四处SUM):

DECLARE @datetest TABLE (dt DATETIME NOT NULL) 

INSERT INTO @datetest (dt) 
VALUES (0) 
INSERT INTO @datetest (dt) 
VALUES (1) 
INSERT INTO @datetest (dt) 
VALUES (2) 
INSERT INTO @datetest (dt) 
VALUES (0.5) 

SELECT * 
FROM @datetest 

SELECT CONVERT(DATETIME, SUM(CONVERT(FLOAT, dt))) 
FROM @datetest 

我并不是主张这样做,YMMV和您选择的任何设计解决方案都应该根据您的所有要求进行验证。

相关问题