0

我有一个有两DATETIME列的表:

Column1              Column2
1/1/1900 12:20:45    1/1/1900 23:22:25
1/1/1900 09:00:00    1/1/1900 18:10:30
…                    …

(时间格式为HH:MM:SS。)

我想取第 1 列和第 2 列的总数。如果表格只有上面显示的两行,则预期结果将是:

Column1              Column2 
1/1/1900 21:20:45    1/1/1900 41:32:55

请注意,小时、分钟和秒不应超过 60。

如何在 SQL Server 2000 中对这些列求和?

4

7 回答 7

0
select Column1+Column2 from table
于 2009-09-30T13:24:08.183 回答
0
SELECT Column1 + Column2 AS MyResult FROM YOURTABLE
于 2009-09-30T13:25:29.040 回答
0

此示例应说明您需要执行的操作:

declare @Base datetime set @base = '1900-01-01'
declare @first datetime set @first = '1900-01-01 12:15:00'
declare @other datetime set @other = '1900-01-01 01:00:00'

select DATEADD(s, SUM(DATEDIFF(s, @base, dt)),@base)
from 
(
    select @first as dt
    union select @other 
) t

我的 Sql Server 2000 机器上的 QA 输出是:

1900-01-01 13:15:00.000

于 2009-09-30T13:26:01.507 回答
0

预期输出 column1 column2 1/1/1900 21:20:45 1/1/1900 41:32:55

这是行不通的,因为 SQL Server 2000 中的 DATETIME 被限制为 24 小时。

因此,为了总结您的小时数,我想您必须将其分解为小时、分钟、秒作为 INT 列,然后执行类似的操作

UPDATE dbo.YourTable
SET SumHours = DATEPART(HOUR, CONVERT(DATETIME, Column1, 100)),
    SumMinutes = DATEPART(MINUTE, CONVERT(DATETIME, Column1, 100)),
    SumSeconds = DATEPART(SECOND, CONVERT(DATETIME, Column1, 100))
WHERE........

(对于第 2 列也是如此)。

我真的没有看到任何其他方式。此外,您可以将分钟 > 60 转换为小时+分钟和秒 > 60 转换为分钟+秒。

马克

于 2009-09-30T13:55:26.130 回答
0

我的假设:您的日期时间正在跟踪经过的时间。例如,您的第一个值“1900 年 1 月 1 日 12:20:45”表示在(无论如何)期间经过了 12 小时、20 分钟和 45 秒。鉴于此,您希望将所有这些经过的时间相加,产生“总经过时间”。

这是一种方法。(可能还有其他的——似乎总是有更好的方法来实现时间数学。)我只查询一列以使示例更清晰,并适当偏执。我进一步假设日期部分(a)完全不相关,(b)可以设置为任何内容。[当然,如果您使用 SQL 2008,您希望将列设置为 Time 数据类型。] 最后一列 [5] 是您想要的;其他人解释了我是如何到达那里的。

select
   MyColumn  --  [1]
  ,dateadd(dd, -datediff(dd, 0, MyColumn), MyColumn)  --  [2]
  ,datediff(ss, 0, dateadd(dd, -datediff(dd, 0, MyColumn), MyColumn))  --  [3]
 from MyTable

select
   sum(datediff(ss, 0, dateadd(dd, -datediff(dd, 0, MyColumn), MyColumn)))  --  [4]
  ,dateadd(ss, sum(datediff(ss, 0, dateadd(dd, -datediff(dd, 0, MyColumn), MyColumn))), 0)  --  [5]
 from MyTable

[1] 显示每行的初始值。
[2] 将每一列的日期部分转换为“1900 年 1 月 1 日”。如果您非常确定您的日期将始终相同,则无需考虑这一点。
[3] 这会计算午夜和记录时间之间经过的秒数。
[4] 这是秒的总和。
[5] 这会将经过的时间(以秒为单位)重新添加到“1900 年 1 月 1 日”。

从那里,使用您使用的任何标准格式化技术将结果显示为经过时间(不要忘记考虑日期,因为经过时间可能超过 24 小时)。这种技术对于任何时间单位都是准确的(在这里,如您所愿,我使用秒),但请注意,如果经过时间的单位总数超过 (2^31 - 1),因为它会持续毫秒,您可能需要转换为 bigints。

嗯,只是想:如果单个经过的时间大于 24 小时怎么办?在这种情况下,您的日期时间的日期很重要,并且必须代表“开始日期”。更糟糕的是,我们不能假设样本池中最早的日期是基准日期,因为所有经过的时间都可能是 24 小时或更长时间。为此,您需要某种方法来确定要计算的“基准日期”。由于您的问题中没有任何迹象表明基准日期可能是什么,因此我将作为最后的假设假设这不是问题 - 您所有经过的时间都将在 24 小时内。

于 2009-09-30T14:31:14.163 回答
0
SELECT DATEADD(s, 0, SUM(DATEDIFF(s, 0, Column1))) AS SUMColumn1
    ,DATEADD(s, 0, SUM(DATEDIFF(s, 0, Column2))) AS SUMColumn2
FROM tbl
于 2009-09-30T14:39:27.647 回答
0

这会给你你所追求的:

CREATE TABLE #Times
(
     Column1 datetime
    ,Column2 datetime
)

INSERT INTO #Times VALUES ('1/1/1900 12:20:45',    '1/1/1900 23:22:25')
INSERT INTO #Times VALUES ('1/1/1900 09:00:00',    '1/1/1900 18:10:30')

SELECT
     CONVERT(varchar(10),dateadd(day,datediff(day,0,dt2.MinColumn1),0),101)
         +' '
         +CASE WHEN TotalSecondsColumn1/3600>60 then '60' ELSE CONVERT(varchar(2),TotalSecondsColumn1/3600) END
         +':'
         +CASE WHEN (TotalSecondsColumn1-(TotalSecondsColumn1/3600*3600))/60 >60 then '60' ELSE CONVERT(varchar(2),(TotalSecondsColumn1-(TotalSecondsColumn1/3600*3600))/60) END
         +':'
         +CASE WHEN TotalSecondsColumn1-((TotalSecondsColumn1/3600*3600)+(((TotalSecondsColumn1-(TotalSecondsColumn1/3600*3600))/60)*60)) >60 then '60' ELSE CONVERT(varchar(2),TotalSecondsColumn1-((TotalSecondsColumn1/3600*3600)+(((TotalSecondsColumn1-(TotalSecondsColumn1/3600*3600))/60)*60))) END
     AS Column1
    ,CONVERT(varchar(10),dateadd(day,datediff(day,0,dt2.MinColumn2),0),101)
         +' '
         +CASE WHEN TotalSecondsColumn2/3600>60 then '60' ELSE CONVERT(varchar(2),TotalSecondsColumn2/3600) END
         +':'
         +CASE WHEN (TotalSecondsColumn2-(TotalSecondsColumn2/3600*3600))/60 >60 then '60' ELSE CONVERT(varchar(2),(TotalSecondsColumn2-(TotalSecondsColumn2/3600*3600))/60) END
         +':'
         +CASE WHEN TotalSecondsColumn2-((TotalSecondsColumn2/3600*3600)+(((TotalSecondsColumn2-(TotalSecondsColumn2/3600*3600))/60)*60)) >60 then '60' ELSE CONVERT(varchar(2),TotalSecondsColumn2-((TotalSecondsColumn2/3600*3600)+(((TotalSecondsColumn2-(TotalSecondsColumn2/3600*3600))/60)*60))) END
     AS Column1
    FROM #Times t
        INNER JOIN (SELECT
                         SUM(DATEDIFF(second,CONVERT(datetime,LEFT(CONVERT(char(23),Column1,121),10)),Column1)) AS TotalSecondsColumn1
                        ,SUM(DATEDIFF(second,CONVERT(datetime,LEFT(CONVERT(char(23),Column2,121),10)),Column2)) AS TotalSecondsColumn2
                        FROM #Times
                   ) dt ON 1=1
        INNER JOIN (SELECT
                         MIN(Column1) AS MinColumn1
                        ,MIN(Column2) AS MinColumn2
                        FROM #Times
                   ) dt2 ON 1=1
    WHERE t.Column1=dt2.MinColumn1

输出:

Column1             Column1
------------------- -------------------
01/01/1900 21:20:45 01/01/1900 41:32:55

(1 row(s) affected)

但是,这将准确地求和时间,同时增加日、月和年:

SELECT
     DATEADD(second,dt.TotalSecondsColumn1,dateadd(day,datediff(day,0,dt2.MinColumn1),0)) AS Column1
    ,DATEADD(second,dt.TotalSecondsColumn2,dateadd(day,datediff(day,0,dt2.MinColumn2),0)) AS Column2
    FROM #Times t
        INNER JOIN (SELECT
                         SUM(DATEDIFF(second,CONVERT(datetime,LEFT(CONVERT(char(23),Column1,121),10)),Column1)) AS TotalSecondsColumn1
                        ,SUM(DATEDIFF(second,CONVERT(datetime,LEFT(CONVERT(char(23),Column2,121),10)),Column2)) AS TotalSecondsColumn2
                        FROM #Times
                   ) dt ON 1=1
        INNER JOIN (SELECT
                         MIN(Column1) AS MinColumn1
                        ,MIN(Column2) AS MinColumn2
                        FROM #Times
                   ) dt2 ON 1=1
    WHERE t.Column1=dt2.MinColumn1

输出:

Column1                 Column2
----------------------- -----------------------
1900-01-01 21:20:45.000 1900-01-02 17:32:55.000

(1 row(s) affected)
于 2009-09-30T19:00:50.617 回答