什么是在SQL Server数据库中存储时间间隔的最佳方法

时间:2010-03-07 19:15:35

标签: sql-server runtime

我有一张表,我想跟踪时间,因此有效条目可能是:

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

最适合使用哪种字段类型。我显然可以使用varchar。但我认为可能会有更好的东西,因为我想运行查询以总计一些记录的总时间。

5 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分: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 :(得分:2)

取决于您的时间范围 - 将所有内容转换为秒并将该值存储为INT,或者如果您的时间跨度较大,则可能需要分别使用小时,分钟和秒的字段。

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

答案 3 :(得分:2)

正如@Aaronaught所说,使用日期/时间或日期时间(根据需要)数据类型来存储您的值;但这些类型只能及时存储实例而不是时间跨度或持续时间。您需要使用两个字段来存储间隔,例如[time_span_start]和[time_span_end]。两者之间的差异会给你间隔。

您可以通过下载Richard T. Snodgrass撰写的“在SQL中开发面向时间的数据库应用程序”的副本来回答您的问题。它以PDF格式免费提供,请点击此处:

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

答案 4 :(得分:0)

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

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

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

现在,对于行的和,这显然不容易,因此您可以考虑添加DATEDIFF的持久计算列(s,'1/1/1900',间隔)以提供执行SUM的秒数。 / p>

现在,这里是SQL Server感兴趣的地方:

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

事实上:

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

按预期给出'1900-01-04 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,您选择的任何设计解决方案都应该根据您的要求进行验证。