【问题标题】:SQL - Calculate Hours sum using rollupSQL - 使用汇总计算小时总和
【发布时间】:2019-05-05 19:30:34
【问题描述】:

我希望将所有小时的总和作为最后一行的摘要。我正在使用以下查询来获取结果:

create table time_test (type varchar(10),time varchar(10))
insert into time_test values ('A','01:25')
insert into time_test values ('B','02:30')
insert into time_test values ('C','05:56')
insert into time_test values ('D','00:50')

--select * from time_test

SELECT
  type = ISNULL(type, 'Total'),
  time = substring((cast(sum(((cast(substring (time,2,1) as decimal)*60 + cast(substring (time,4,2) as decimal))/60)) as varchar(10))),1,2)+':' + cast((cast((round(((cast((((cast((substring((cast((sum(((cast(substring (time,2,1) as decimal)*60 + cast(substring (time,4,2) as decimal))/60))) as varchar(10))),4,2)) as int))*60)) as decimal)/100)),0)) as int)) as varchar(10))
FROM time_test
GROUP BY ROLLUP(type);

输出:

正如您所见,除了这个总计算工作正常之外,时间不正确。

问题: 请让我知道我在显示数据时哪里出错了。

提前致谢。

【问题讨论】:

    标签: sql sql-server rollup


    【解决方案1】:

    我会首先修复您的数据类型,时间应该存储为time,而不是varchar。然后,一旦你确定了你的数据类型,你就可以把你的数据当作它本来的样子(一次)。

    USE Sandbox;
    GO
    
    CREATE TABLE dbo.time_test ([type] varchar(10),
                                [time] time);
    INSERT INTO dbo.time_test
    VALUES ('A', '01:25'); --Assumes hh:mm
    INSERT INTO dbo.time_test
    VALUES ('B', '02:30');
    INSERT INTO dbo.time_test
    VALUES ('C', '05:56');
    INSERT INTO dbo.time_test
    VALUES ('D', '00:50');
    GO
    
    SELECT ISNULL([type],'Total') AS [Type],
           DATEADD(MINUTE,SUM(DATEDIFF(MINUTE,'00:00',[time])),CONVERT(time(0),'00:00')) AS [Time]
    FROM dbo.time_test
    GROUP BY [type] WITH ROLLUP;
    
    GO
    
    DROP TABLE dbo.time_test;
    

    这会返回:

    Type       Time
    ---------- ----------------
    A          01:25:00
    B          02:30:00
    C          05:56:00
    D          00:50:00
    Total      10:41:00
    

    【讨论】:

    • 使用秒而不是分钟以获得更准确的结果。
    • @SalmanA 我们不知道 OP 样本中的 '05:56' 是什么。 假设他们的数据是mm:ss。我假设hh:mm(根据 SQL 中的评论),但如果没有他们告诉我们,我们无法真正知道。
    • 还有一个问题,我使用varchar类型,我们只能通过转换使用varchar类型吗?
    • @Sunny 为什么不更正表中的数据类型?这是迄今为止更好的选择。否则,您可以将表达式中的值[time] 转换为time(哦,讽刺的是,名为[time] 的列不是time),是的。
    • 实际上这是我的 SP 中的一个临时表,在从其他表集计算字段后,我得到了这些值。
    【解决方案2】:

    我确实有类似的要求并像这样解决了它:

    select type, RTRIM(time/60) + ':' + RIGHT('0' + RTRIM(time%60),2) from
    ( 
        select type= ISNULL(type, 'Total'),
          time= SUM(DATEDIFF(MINUTE, '0:00:00', time))
        from time_test
        GROUP BY ROLLUP(type)
    ) x
    

    我相信这更容易理解也更容易追踪

    type    time
    A       1:25
    B       2:30
    C       5:56
    D       0:50
    Total   10:41
    

    编辑:更新了hour can be more then 24 hours的查询

    select type, RTRIM(time/60) + ':' + RIGHT('0' + RTRIM(time%60),2) from
    ( 
        select type= ISNULL(type, 'Total'),
          time= SUM(DATEDIFF(MINUTE, '0:00:00', 
            DATEADD(day, SUBSTRING(time,0,CHARINDEX(':',time,0)) / 24,
            DATEADD(hour, SUBSTRING(time,0,CHARINDEX(':',time,0)) % 24, 
            DATEADD(minute,SUBSTRING(time,CHARINDEX(':',time)+1,LEN(time)) +0, 0)) )))
        from time_test
        GROUP BY ROLLUP(type)
    ) x
    

    示例结果:

    A       1:25
    B       2:30
    C       5:56
    D       70:50
    Total   80:41
    

    【讨论】:

    • 我得到:消息 241,级别 16,状态 1,行 168 从字符串转换日期和/或时间时转换失败。就我而言,小时数可能超过两位数。比如 120:00。
    • 请检查我更新的答案。如果有效,请接受它作为答案。谢谢你:)
    • 完成 :-)
    【解决方案3】:

    好的,所以快速查看代码,尽量避免使用 VARCHAR 数据类型来存储日期和/或时间。

    以下是我所做的:

    create table time_test (type varchar(10),time1 time)
    insert into time_test values ('A','00:01:30')
    insert into time_test values ('B','00:02:30')
    insert into time_test values ('C','00:01:00')
    insert into time_test values ('D','00:02:30')
    
    SELECT
      type = ISNULL(type, 'Total'),
      seconds_worked = SUM(DATEDIFF(SECOND, '00:00', time1))
      FROM time_test
    GROUP BY ROLLUP(type);
    

    您会看到总计为 450,如果您根据提供的数据手动计算,这似乎是正确的,即总时间为 450 秒。

    您可以使用以下公式以分钟和秒为单位返回您的时间:

    RTRIM(**450**/60) + ':' + RIGHT('0' + RTRIM(**450**%60),2)
    

    【讨论】:

    • 哦对了,SELECT后忘记去掉
      了,你自己做吧
    • 刚刚做了,谢谢,试图适应这里的格式。
    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多