使用Convert()将nvarchar值'3.5'转换为数据类型int时,转换失败

时间:2019-03-02 15:05:10

标签: sql sql-server tsql

ReduceDuties.Confirmed_Time是:(Nvarchar类型)

  Confirmed_Time
|----------------|
|       5        | 
|       3.5      |
|       10       |
|       15       |
|       18       |

我想对数字进行分类。

所需的输出:

1-9   =>  2
9-19  =>  3

我尝试过:

    select t.range as [score range], count(*) as [number of occurences]
from (
      select convert (float , Confirmed_Time) as Taeid,
         case when Confirmed_Time >= 1 and Confirmed_Time <= 9 then '0-9'
         when Confirmed_Time > 9 and Confirmed_Time <= 19 then '9-19'
         end as range
     from ReduceDuties) t
group by t.range

但是出现以下错误:

  

将nvarchar值“ 3.5”转换为数据时,转换失败   输入int。

2 个答案:

答案 0 :(得分:3)

显然,confirmed_time是一个字符串。当您与整数进行比较时,它将尝试以整数进行比较。因此,将转换设为显式

(case when try_convert(float, Confirmed_Time) >= 1 and
           try_convert(float, Confirmed_Time) <= 9
      then '0-9'
 . . .

我的建议是永远不要依赖隐式转换。它引入了很难发现的错误。

如果您希望将此值作为十进制值(对我而言,它比int更有意义),则应更改表中的类型。如果由于某种原因(例如某些值不是数字)而无法实现,则可以添加新列:

alter table ReduceDuties add confirmed_time_dec as (try_convert(decimal(10, 2), Confirmed_Time));

然后您可以在查询中安全地使用confirmed_time_dec

答案 1 :(得分:3)

问题是您没有在CASE表达式内进行从文本到数字的转换。我可能只是从CTE开始,首先进行转换:

WITH cte AS (
    SELECT CONVERT(float, Confirmed_Time) AS Confirmed_Time
    FROM ReduceDuties
)

SELECT
    Confirmed_Time,
    CASE WHEN Confirmed_Time BETWEEN 1 AND 9  THEN '0-9'
         WHEN Confirmed_Time BETWEEN 9 AND 19 THEN '9-19'
    END AS range
FROM cte;

如果您确实打算将确认的时间列主要用作数字,则应该将其设为数字​​类型列。然后,如果您仍然需要偶尔将其用作文本,只需根据需要进行转换。