我在表TotalHours
中有一个类型为float
的列。
值为
小时列所遵循的格式类似于hours.min
我想得到总和
我正在使用的查询是
select sum(TotalHours) as hours from workdone where userid = 3
因此它返回8.9
这是错误的,首先我需要将其转换为小时数,然后取得总和,但我被卡住了。
如何将值转换为小时并获得总和?
已修改:总和值将再次为浮动格式。
例如,总和结果应为9.3
答案 0 :(得分:1)
这不是存储持续时间的好方法。存储十进制秒,分钟,小时是好的,但它应该是基数10,即1小时30分钟,应该是1.5小时,或90分钟,而不是1.3 - 如果有人在您的表中插入1.7怎么办?添加/减去以秒/分钟存储的数据,并根据需要重新格式化也更加简单。
无论如何,你可以使用一些相当简单的逻辑进行转换。小时部分将只是小数点之前的部分,即数字的整数部分,这可以通过将数字向下舍入来获得 - 例如FLOOR(1.3)
= 1小时。然后得到你需要提取数字的小数部分并乘以100的分钟数 - 例如从1.3中提取0.3并将其乘以100得到30分钟。
SELECT [Hours] = FLOOR(n),
[Minutes] = (n - FLOOR(n)) * 100,
TotalMinutes = (FLOOR(n) * 60) + (n - FLOOR(n)) * 100,
SummedMinutes = SUM((FLOOR(n) * 60) + (n - FLOOR(n)) * 100) OVER(),
SummedHours = SUM((FLOOR(n) * 60) + (n - FLOOR(n)) * 100) OVER() / 60.0
FROM (VALUES (3.4), (1.3), (4.2)) t (N);
然后,如果你需要将9.5小时转换回9.3(再次,这是表示9小时30分钟的可怕方式),你需要反转上面的逻辑,即总小时数+(分钟/ 100)
SELECT [Hours] = CAST(FLOOR(SummedMinutes / 60) AS FLOAT),
[Minutes] = SummedMinutes % 60,
OddFormat = CAST(FLOOR(SummedMinutes / 60) AS FLOAT) + (SummedMinutes % 60 / 100)
FROM ( SELECT SummedMinutes = SUM((FLOOR(n) * 60) + (n - FLOOR(n)) * 100)
FROM (VALUES (3.4), (1.3), (4.2)) t (N)
) AS t;
<强> Example on SQL Fiddle 强>
答案 1 :(得分:0)
尝试此查询以总结小时和分钟:
DECLARE @Result AS INT
SELECT @Result = SUM(SubString(CAST(CAST(TOTALHOUR AS DECIMAL(10,2))
AS VARCHAR(10)), 0, Charindex('.', CAST(CAST(TOTALHOUR AS DECIMAL(10,2))
AS VARCHAR(10)))) * 60 + SubString(CAST(CAST(TOTALHOUR AS DECIMAL(10,2))
AS VARCHAR(10)), Charindex('.', CAST(CAST(TOTALHOUR AS DECIMAL(10,2))
AS VARCHAR(10))) + 1, len(CAST(CAST(TOTALHOUR AS DECIMAL(10,2))
AS VARCHAR(10)))))
FROM WORKDONE
WHERE userid = 3
SELECT @Result, CAST(@Result / 60
AS VARCHAR(10)) + ':' + CAST(@Result % 60
AS VARCHAR(10))
AS ExpectedResult
ExpectedResult = 9:30
答案 2 :(得分:0)
这应该有效:
SELECT sum(CAST(TotalHours as int))
+ sum(cast(Parsename(cast((TotalHours) as decimal(10,2)),1) as int))/60
+ (sum(cast(Parsename(cast((TotalHours) as decimal(10,2)),1) as int))%60) *0.01
FROM workdone
WHERE userid = 3
答案 3 :(得分:-2)
你可以使用这种正则表达式来分隔数字和它们的十分位数,你就可以实现结果。下面是示例,您需要将其应用于所有行并总结
select (regexp_substr('4.2','[[:digit:]]',1)*60 +
replace(regexp_substr('4.2','\.[[:digit:]]'),'.')*10)/60
from dual;