我在表PriceTerm中有一个varchar列,其中包含各种字符串。所以我想将其中一些复制到另一列。
所以源名称和格式是
[AdditionalDescription] [varchar](255) NOT NULL
和目的地
[PercentAddition] [decimal](28, 10) NOT NULL
我只想转换那些包含SQL挑选的%:
select AdditionalDescription from PriceTerm where AdditionalDescription like '%[%]%'
输出是这样的。
AdditionalDescription
7,5 %
7,5%
7,5%
6 %
7,5%
6 %
3 %
....
返回1696475行,所以很多。
显然我必须删除%符号才能将其转换为十进制值。
所以我认为这是几个子步骤。
我的问题是如何实施第2步和第3步?
更新 我试过那两个SQL。
SELECT
CONVERT(decimal(28,10), LTRIM(RTRIM(REPLACE(REPLACE([ADDITIONALDESCRIPTION], ',', '.'), '%', ''))))
FROM PriceTerm
WHERE AdditionalDescription like '%[%]%'
SELECT
CAST(LTRIM(RTrim(REPLACE(REPLACE([ADDITIONALDESCRIPTION], ',', '.'), '%', ''))) AS Decimal(28,10))
FROM PriceTerm
WHERE AdditionalDescription like '%[%]%'
两者都返回了相同的错误。
将数据类型varchar转换为数字时出错。
但以下作品
选择 CONVERT(十进制(28,10),LTRIM(RTRIM(REPLACE('5,8%',',','。'),'%',''))))) 来自PriceTerm 其他描述如'%[%]%'
我尝试列出那些符合条件并且转换失败的人。
选择 LTRIM(RTRIM(REPLACE(REPLACEALDESCRIPTION),',','。'),'%','')))作为PercentAddition 来自PriceTerm WHERE(AdditionalDescription,如'%[%]%')和ISNUMERIC(LTRIM(RTRIM(REPLACE([ADDITIONALDESCRIPTION],',','。'),'%',''))))= 0
PercentAddition
express + 30
Express Transport +30
tillägg till faktura 115423. express +30
+ 30 (1.30*42.4sek=55.12sek)
+ 30 (1.30*42.4sek=55.12sek)
7.5*
7.5*
7..5
7..5
7.5.
7.5.
1.5 (minimi 4.20 €)
335 * 25 = 418.75
335 * 25= 418.75
10.6 &
vastaanottajan rahdinmaksu +4
Expressfrakt!!+30
奇怪的是,这些都不包含%char。
更新2: 我尝试过滤掉无法使用此SQL转换的数据
SELECT AdditionalDescription
FROM PriceTerm
WHERE Created BETWEEN '2004' AND '2005' AND
AdditionalDescription like '%[%]%' AND
PercentAddition = 0 AND
ISNUMERIC(RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.')))) = 0
输出:
AdditionalDescription
Snabbleverans + 30 %
Snabbleverans + 30 %
455 € + 4%
1,5 % (minimi 4,20 €)
1,5 % (minimi 4,20 €)
bränsle 7,5% ingår.
所以这些字符串包含%但不能将它们转换为小数。我想跳过那些。
计算有效数字
SELECT Count(*)
FROM PriceTerm
WHERE Created BETWEEN '2004' AND '2005' AND
AdditionalDescription like '%[%]%' AND
PercentAddition = 0 AND
ISNUMERIC(RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.')))) = 1
80051
更新PercentAddition列
UPDATE PriceTerm
SET PercentAddition = CONVERT(decimal(28,10), RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.'))))
WHERE Created BETWEEN '2004' AND '2005' AND
AdditionalDescription LIKE '%[%]%' AND
PercentAddition = 0
AND ISNUMERIC(RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.')))) = 1
结果
将数据类型varchar转换为数字时出错。
任何有暗示原因的人?
更新3:
因此,例如,无法解析上面所有那些奇怪的行是gonne被滑倒。
+ 30 (1.30*42.4sek=55.12sek)
7.5*
7.5*
7..5
以上所有内容都将转换为0.只有那些将转换为十进制:
7,5% -> 7.5
7,7 % -> 7.7
2.5 -> 2.5
我还试图找出SQL CASE WHEN的工作原理。可能有用吗? 试过这个:
UPDATE PriceTerm
SET PercentAddition =
CASE
WHEN ISNUMERIC(RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.')))) = 1 THEN
CONVERT(decimal(28,10), RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.'))))
ELSE
0.0
END
WHERE Created BETWEEN '2004' AND '2005' AND
AdditionalDescription LIKE '%[%]%' AND
PercentAddition = 0
AND ISNUMERIC(RTRIM(LTRIM(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.')))) = 1
输出仍然将数据类型varchar转换为数字时出错。 我甚至考虑过一个存储过程,但我之前从未使用过它。 SQL Server 2012具有Try_Convert,在这种情况下非常有用。但我没有找到类似2008 R2的替代品。
答案 0 :(得分:2)
不要考虑效率如何:
Select convert(decimal(28,10), rtrim(ltrim(replace(REPLACE(AdditionalDescription,'%',''), ',','.')))) As AdditionalDescription
from PriceTerm
where AdditionalDescription like '%[%]%'
说明:
,
替换为.
decimal(28, 10)
。根据OP的附加信息。
Select
convert(decimal(28,10),replace(replace(replace(rtrim(ltrim(AdditionalDescription)), ' ',''),',','.'),'%','')) AS PercentAddition
from test
where replace(rtrim(ltrim(AdditionalDescription)), ' ','')
like '[0-9]%[,.]%[%0-9]'
and
isnumeric(replace(replace(replace(rtrim(ltrim(AdditionalDescription)), ' ',''),',','.'),'%',''))=1
'[0-9]%[,.]%[%0-9]'
的解释:
[0-9]
- 我们只对数据以数字开头时感兴趣。%
- 数字后可能包含任何字符。我们在isnumeric
子句中使用where
来处理非数字。[,.]
- 我们的数据包含,
或.
。%
- 在[,.]
之后,它可能包含任何字符。我们在isnumeric
子句中使用where
来处理非数字。[%0-9]
- 我们希望数据以数字或%
结尾。 注意:当您发现更多不良字符时,您必须修改'[0-9]%[,.]%[%0-9]'
。
<强>参考文献:强>
答案 1 :(得分:1)
这不是最快的方法,但试试这个:
SELECT CONVERT(DECIMAL(5, 2), REPLACE(REPLACE(AdditionalDescription, '%', ''), ',', '.')) AS DecimalValue
FROM PriceTerm
WHERE AdditionalDescription LIKE '%[%]%'
这将用空字符串替换%和带点的逗号,因此7,5%将看起来像7.5然后转换为小数。
答案 2 :(得分:1)
事实证明,如果字符串是数字,最难的部分是验证。内置程序IsNumeric返回误报。即使结果为1,CONVERT也无法将字符串转换为Decimal。谷歌和site
提供了救援我使用存储过程。
CREATE FUNCTION dbo.isReallyNumeric
(
@num VARCHAR(64)
)
RETURNS BIT
BEGIN
IF LEFT(@num, 1) = '-'
SET @num = SUBSTRING(@num, 2, LEN(@num))
DECLARE @pos TINYINT
SET @pos = 1 + LEN(@num) - CHARINDEX('.', REVERSE(@num))
RETURN CASE
WHEN PATINDEX('%[^0-9.-]%', @num) = 0
AND @num NOT IN ('.', '-', '+', '^')
AND LEN(@num)>0
AND @num NOT LIKE '%-%'
AND
(
((@pos = LEN(@num)+1)
OR @pos = CHARINDEX('.', @num))
)
THEN
1
ELSE
0
END
END
GO
并像这样使用它:
UPDATE PriceTerm
SET PercentAddition = CONVERT(decimal(28,10), RTRIM(LTRIM(REPLACE(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.'), '&', ''))))
WHERE AdditionalDescription LIKE '%[%]%' AND
dbo.isreallynumeric(RTRIM(LTRIM(REPLACE(REPLACE(REPLACE(AdditionalDescription,'%',''), ',','.'), '&', '')))) = 1 AND
PercentAddition = 0