如何汇总存储在varchar列中的时间跨度?

时间:2014-10-11 15:27:58

标签: sql sql-server

我在MS SQL-Server中有一个表,它在varchar列中有几个小时。对于前者'4:30'(小时:分钟)。基本上这是一个工作量的时间跨度。现在我需要这个专栏的总和。如何转换它?

我的表格看起来像这样

Create table tblWrkingHors
(
    Id int primary key,
    name varchar(50),
    WorkingHr varchar(8)
)

我的表格数据是这样的

==============================================================
Id       name       WorkingHr 
1        sam         08:20
2        sam         04:50
3        sam         04:34
4        Pam         05:50
5        sam         04:30
6        Pam         06:40
7        Pam         04:50
8       Todd         06:10
9       Todd         05:50
10      Todd         08:50   

3 个答案:

答案 0 :(得分:2)

VARCHAR可能不是最有效的存储时间版本,但通过一点点投射,你可以做你想要的事情;

WITH cte AS (
  SELECT name, SUM(DATEDIFF(MINUTE, '00:00', CAST(WorkingHr AS TIME))) t
  FROM mytable GROUP BY name
)
SELECT name, RTRIM(t/60) + ':' + RIGHT('0' + RTRIM(t%60), 2) FROM cte

An SQLfiddle to test with

它基本上做的是将字符串转换为TIME,然后使用DATEDIFF将时间转换为分钟。然后它基本上总结了每个名字的分钟数。

外部查询只使用简单的字符串操作将分钟转换为HH:MM字符串。

如果您不想按名称分组,可以将查询简化为;

WITH cte AS (
  SELECT SUM(DATEDIFF(MINUTE, '00:00', CAST(WorkingHr AS TIME))) t FROM mytable
)
SELECT RTRIM(t/60) + ':' + RIGHT('0' + RTRIM(t%60), 2) FROM cte;

...这是几乎没有分组的查询。

答案 1 :(得分:1)

SQL Fiddle

MS SQL Server 2012架构设置

CREATE TABLE Test_Table(Id INT, name VARCHAR(10), WorkingHr VARCHAR(8))
INSERT INTO Test_Table VALUES
(1        ,'sam' ,'08:20'),
(2        ,'sam' ,'04:50'),
(3        ,'sam' ,'04:34'),
(4        ,'Pam' ,'05:50'),
(5        ,'sam' ,'04:30'),
(6        ,'Pam' ,'06:40'),
(7        ,'Pam' ,'04:50'),
(8       ,'Todd' ,'06:10'),
(9       ,'Todd' ,'05:50'),
(10      ,'Todd' ,'08:50')

查询1

SELECT name
      ,CAST(DATEADD(MILLISECOND, 
               SUM(DATEDIFF(MILLISECOND, '00:00:00.000'
         , CAST(WorkingHr AS TIME))), '00:00:00.000') AS TIME) AS Total_Time
FROM Test_Table
GROUP BY name

<强> Results

| NAME |       TOTAL_TIME |
|------|------------------|
|  Pam | 17:20:00.0000000 |
|  sam | 22:14:00.0000000 |
| Todd | 20:50:00.0000000 |

答案 2 :(得分:1)

在求和之前将时间转换为分钟数

SELECT
   SUM( 60 * CONVERT(int, LEFT( WorkingHr, 2)) +
             CONVERT(int, RIGHT(WorkingHr, 2))   ) AS TotalMinutes
FROM tblWorkingHours;

或者,如果您需要每人的总和:

SELECT
   name,
   SUM( 60 * CONVERT(int, LEFT( WorkingHr, 2)) +
             CONVERT(int, RIGHT(WorkingHr, 2))   ) AS TotalMinutes
FROM tblWorkingHours
GROUP BY name;

但是varchar数据类型可能不是最佳选择。将时间跨度以分钟数存储为int。应用程序(前端)负责以适当的格式转换和显示数据,而不是数据库的责任。因此,请选择最适合计算的数据类型,而不是显示。