比较varchar列中的小数值

时间:2011-08-10 22:44:35

标签: sql sql-server tsql sqldatatypes

我有一个名为XYZ的varchar列,该列中的值类似于

XYZ
10.2
9.0
97.32

当我写一个类似

的案例陈述时
CASE 
    WHEN XYZ > '9.0' THEN
    'DONE'
    WHEN XYZ < '7.0' THEN
    'NOT DONE'
    WHEN XYZ BETWEEN '7.0' AND '9.0' THEN
    'NULL'
     END

不与价值进行比较。应该怎么做才能解决这个问题?

4 个答案:

答案 0 :(得分:2)

如果您知道数据是干净的,则可以在该字段上运行强制转换(或转换)语句 CASE WHEN CAST(XYZ AS decimal) > 9.0 THEN 'DONE' WHEN CAST(XYZ AS decimal) < 7.0 THEN 'NOT DONE' WHEN CAST(XYZ AS decimal) BETWEEN 7.0 AND 9.0 THEN 'NULL' END

请注意,您应该丢失'9.0'周围的报价 另外值得注意的是,施法操作将针对整个场进行。这将使索引的使用变得无用,因为它必须扫描整个表以进行转换才能进行比较。即使是中等大小的表(即10-100k记录),这也会产生严重的性能影响。

答案 1 :(得分:2)

如果列确实只表示数字,并且从不希望包含除数字之外的任何其他内容,那么只需执行将列转换为更合适类型的一次性操作。根据数据的性质,您可能需要在精确类型和近似类型之间进行选择,即decimalfloat / real。对于前者,您还必须选择正确的精度和比例(小数点后的位数)。

转换本身看起来基本上是这样的:

ALTER TABLE atable
ALTER COLUMN XYZ decimal(15, 2)

同样,您需要确保列中没有非数字值,否则语句将失败。

答案 2 :(得分:0)

在进行强制转换之前,您需要确定数据是否为数字。 Denali有一个TRY_CONVERT函数,但在之前的版本中,您需要使用CASE WHEN ISNUMERIC(XYZ + 'e0') = 1语句,该语句可以合并到主CASE中,也可以如下所示分开

DECLARE @YourTable TABLE
(
XYZ VARCHAR(50)
)

INSERT INTO @YourTable
SELECT 'foo' AS XYZ
UNION ALL 
SELECT '8.9'
UNION ALL 
SELECT '9.1'
UNION ALL 
SELECT '6.5'

SELECT 
CASE 
    WHEN _XYZ > 9 THEN
    'DONE'
    WHEN _XYZ < 7 THEN
    'NOT DONE'
     END
FROM @YourTable
CROSS APPLY(SELECT CASE WHEN ISNUMERIC(XYZ + 'e0') = 1 
            THEN CAST(XYZ AS NUMERIC(18,8)) END) CA(_XYZ)

答案 3 :(得分:0)

WHEN ISNUMERIC(XYZ) = 0 
                                THEN 'DONE'
                WHEN CONVERT(DECIMAL,XYZ) > 9 
                                THEN 'NOT DONE'
                WHEN CONVERT(DECIMAL,XYZ) < 7.0 
                                THEN 'SOMETIMES DONE'
                WHEN CONVERT(DECIMAL,XYZ) BETWEEN 7.0 AND 9.0 
                                THEN 'EVERYTIME DONE'
                WHEN ISNULL(XYZ,'') = '' 
                                THEN 'NONE'
END 
雅虎完成了!这对我有用。 感谢您的帮助和有用的建议 适应所有时间。