Sql 如何对字符串函数使用Sum?

Sql 如何对字符串函数使用Sum?,sql,sql-server,sum,substring,Sql,Sql Server,Sum,Substring,一名员工有多个合同工时,我想计算每个员工的合同总工时,但总合同工时列中的数据格式为:35.00-合同工时 尝试运行以下脚本时: SELECT DISTINCT EmpId ,Substring(Contract_Hours,1,5) AS TotalContractHours ,SUM(CAST(Substring(Contract_Hours,1,5) AS INT)) --OR ,SUM(CAST(Substring(Contract_Hours,1,5) AS deci

一名员工有多个合同工时,我想计算每个员工的合同总工时,但总合同工时列中的数据格式为:35.00-合同工时 尝试运行以下脚本时:

SELECT DISTINCT
   EmpId
  ,Substring(Contract_Hours,1,5) AS TotalContractHours
  ,SUM(CAST(Substring(Contract_Hours,1,5) AS INT))
  --OR ,SUM(CAST(Substring(Contract_Hours,1,5) AS  decimal(1,1)))

FROM tbl.Employee

GROUP BY 
  EmpID
 ,Substring(Contract_Hours,1,5)
我得到一个错误:

Msg 245,16级,状态1,第1行

将varchar值“28.00”转换为数据时,转换失败 输入int

我试着在不使用sum聚合的情况下运行它,它成功了,所以我认为这与sum和未转换的数据类型有关


我做错了什么?请提供帮助

因为小时的格式为xx.yy,您有两个选项:

1.仅取整数部分并强制转换为int: 2.取整部分并转换为小数:
错误在子字符串中。子字符串(1,2)将起作用

但是,a(1,5)不会。很可能是因为小数点。您可能需要将转换/强制转换为十进制,然后再转换回整数

像这样:

SELECT DISTINCT
   EmpId
  ,Substring(Contract_Hours,1,5) AS TotalContractHours
  ,SUM(Convert(int,CAST(Substring(Contract_Hours,1,5) AS decimal(18,2))))
  --OR ,SUM(CAST(Substring(Contract_Hours,1,5) AS  decimal(1,1)))

FROM tbl.Employee

GROUP BY 
  EmpID
 ,Substring(Contract_Hours,1,5)

您可以先尝试将该值转换为数值。随后将其转换为十进制。使用以下代码,它应该可以工作

SUM(CAST(CAST(Contract_Hours AS decimal(10,2)) AS int))

如果您真的被这种糟糕的设计所困扰,那么我会尝试结束您的查询以使其尽可能安全,例如:

SELECT
    EmpId,
    LEFT(Contract_Hours, 5) AS TotalContractHours,
    SUM(CONVERT(INT, CASE WHEN ISNUMERIC(LEFT(Contract_Hours, 5)) = 1 THEN CONVERT(NUMERIC(19,2), LEFT(Contract_Hours, 5)) ELSE 0 END)) AS SummedHours
FROM 
    tbl.Employee
GROUP BY 
    EmpID,
    LEFT(Contract_Hours, 5);
这是怎么回事


我们不需要麻烦使用
子字符串
,因为您总是从字符串的最左边开始,所以
LEFT
更简单
ISNUMERIC
将告诉我们是否以一个数字结束,以避免我们通过尝试
某个字符串转换为数字而出现异常。因此,如果最左边的5个字符是数字,我们将它们转换成2dp十进制,然后转换成INT,然后求和。

将整数存储为varchar的原因是什么?更改列的类型,无需使用任何解决方法,一切都将正常。请改为
DECMAL(18,2)
,否?无需在此处选择DISTINCT,您的分组将不会返回重复项。xx.yy是什么意思?yy分数是小时还是分钟?yy分数是分钟。我没有权限更改数据类型。该列的数据类型为nvarchar,使用字符串从合同小时数中提取35.00将意味着必须转换该数据类型以执行小时数总和。您好,谢谢您的回答。我试过使用这些数据,但似乎不起作用。第一个错误消息如下:子字符串函数需要3个参数。第二个错误消息如下:子字符串函数需要3个参数。请执行更新。是用来证明工作的,不是答案。更新答案代码以更正格式谢谢大家。理查德成功了。现在唯一的问题是复制品。我在Select语句中添加了Distinct。。。。但它仍在按EmpID添加所有合同工时的副本。。例如:EMPID1有160个重复记录,合同工时39,我将得到6240个总工时。我怎样才能解决这个问题,让它只计算合同的总小时数,而不需要重复,这样我就能得到准确的合同总小时数。谢谢大家,这很有效。现在唯一的问题是复制品。我在Select语句中添加了Distinct。。。。选择不同的EmpId,左(合同工时,5)作为TotalContractHours,SUM(转换(INT,当为数字时为大小写(左(合同工时,5))=1,然后转换(数字(19,2),左(合同工时,5))或0结束)作为tbl中的SummedHours。员工组按EmpId,左(合同工时,5);谢谢大家。理查德成功了。现在唯一的问题是复制品。我在Select语句中添加了Distinct。。。。但它仍在按EmpID添加所有合同工时的副本。。例如:EMPID1有160个重复记录,合同工时39,我将得到6240个总工时。我如何才能解决这个问题,使其只计算合同工时的总和,而不需要重复,这样我就能得到准确的合同工时总数
SUM(CAST(CAST(Contract_Hours AS decimal(10,2)) AS int))
SELECT
    EmpId,
    LEFT(Contract_Hours, 5) AS TotalContractHours,
    SUM(CONVERT(INT, CASE WHEN ISNUMERIC(LEFT(Contract_Hours, 5)) = 1 THEN CONVERT(NUMERIC(19,2), LEFT(Contract_Hours, 5)) ELSE 0 END)) AS SummedHours
FROM 
    tbl.Employee
GROUP BY 
    EmpID,
    LEFT(Contract_Hours, 5);