我有一张表,我想跟踪时间,因此有效条目可能是:
最适合使用哪种字段类型。我显然可以使用varchar。但我认为可能会有更好的东西,因为我想运行查询以总计一些记录的总时间。
答案 0 :(得分:13)
不使用字符类型存储日期/时间信息。
在SQL Server 2008中,您具有time
类型,如果您的时间间隔小于1天,则应使用此类型。在以前的版本中,或者如果您需要存储更大的间隔,则必须使用datetime
或smalldatetime
(取决于您需要的精度)。
另一种选择是选择时间单位 - 比如分钟 - 并且只使用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格式免费提供,请点击此处:
答案 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,您选择的任何设计解决方案都应该根据您的要求进行验证。