我有一个名为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
不与价值进行比较。应该怎么做才能解决这个问题?
答案 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)
如果列确实只表示数字,并且从不希望包含除数字之外的任何其他内容,那么只需执行将列转换为更合适类型的一次性操作。根据数据的性质,您可能需要在精确类型和近似类型之间进行选择,即decimal
和float
/ 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
雅虎完成了!这对我有用。
感谢您的帮助和有用的建议
适应所有时间。