[英]Extracting Fraction from Number stored as string
I've got a field in this database that stores number like so: 我在这个数据库中有一个字段,存储数字如下:
I'm trying to convert these to a full decimal so I can add them up. 我正在尝试将这些转换为完整的小数,以便我可以将它们添加起来。 I've been trying to do this by extracting the fraction out of the number, converting that to a decimal and then adding that to the whole number. 我一直试图通过从数字中提取分数,将其转换为小数,然后将其添加到整数来尝试这样做。 I've been having some major problems extracting the numerator. 我在提取分子时遇到了一些重大问题。 The denominator has been extracted using: 分母已经使用以下方法提取:
CASE WHEN CHARINDEX('/',Fraction) > 0 THEN RIGHT(Faction,(LEN(Fraction) - (CHARINDEX('/',Fraction)))) ELSE NULL END AS [Denominator]
I'm not sure if that's the most efficient way to do it but it seems to work. 我不确定这是否是最有效的方法,但似乎有效。
I've tried to pull the numerator out using this method: 我试图用这种方法拉出分子:
CASE WHEN Charindex('/', Fraction) > 0 THEN LEFT(RIGHT(Fraction, Len(Fraction) - Charindex(' ',Fraction)), CHARINDEX('/',Fraction) - 1) ELSE NULL END AS [Numerator]
But that just gives me the fraction itself. 但这只是给了我自己的分数。 I'm not sure if SQL has a problem with a RIGHT inside a LEFT since it doesn't seem to do anything, or, more likely, my code is messed up. 我不确定SQL在LEFT中是否存在RIGHT问题,因为它似乎没有做任何事情,或者更可能的是,我的代码搞砸了。
Anyone have any ideas? 有人有想法么?
Thanks! 谢谢!
You almost got it right: you are calculating the length that you pass to LEFT
incorrectly. 你几乎做对了:你正在计算你传递给LEFT
的长度不正确。 You need to take the position of space into account. 您需要考虑空间位置。
Instead of 代替
CHARINDEX('/',Fraction) - 1
the length should be 长度应该是
CHARINDEX('/',Fraction) - CHARINDEX(' ',Fraction) - 1
The overall expression should look like this: 整体表达式应如下所示:
CASE WHEN Charindex('/', Fraction) > 0 THEN LEFT(RIGHT(Fraction, Len(Fraction) - Charindex(' ',Fraction)), CHARINDEX('/',Fraction) - CHARINDEX(' ',Fraction) - 1) ELSE NULL END AS [Numerator]
This should work. 这应该工作。 I've moved the CHARINDEX functions to inside an APPLY just to try and make it more legible 我已将CHARINDEX函数移到APPLY内部,试图让它更清晰
WITH Data AS
( SELECT Fraction
FROM (VALUES
('80 1/4'),
('20 1/8'),
('20'),
('36 15/16'),
('44 1/8'),
('93 7/8'),
('89 1/8')
) t (Fraction)
), Workings AS
( SELECT Fraction,
WholeNumber = CAST(CASE WHEN FractionIndex = 0 THEN Fraction ELSE LEFT(Fraction, SpaceIndex) END AS FLOAT),
Numerator = CAST(CASE WHEN FractionIndex > 0 THEN SUBSTRING(Fraction, SpaceIndex, FractionIndex - SpaceIndex) END AS FLOAT),
Demonimator = CAST(CASE WHEN FractionIndex > 0 THEN SUBSTRING(Fraction, FractionIndex + 1, LEN(Fraction)) END AS FLOAT)
FROM Data
CROSS APPLY
( SELECT FractionIndex = CHARINDEX('/', Fraction),
SpaceIndex = CHARINDEX(' ', Fraction)
) f
)
SELECT *,
[Decimal] = CAST(WholeNumber + COALESCE(Numerator / Demonimator, 0) AS FLOAT)
FROM Workings
Here is something you can try: 您可以尝试以下方法:
with t as (select '80 123/456' as val)
select (case when val like '% %/%'
then cast(left(val, charindex(' ', val)) as float) +
(cast(SUBSTRING(val, charindex(' ', val), CHARINDEX('/', val) - charindex(' ', val)) as float) /
CAST(SUBSTRING(val, charindex('/', val)+1, 100) as int)
)
else cast(val as float)
end)
from t
Just copy replace the variable with your column name and place in the portion of your case statement where your "CHARINDEX('/',Fraction) > 0" is true. 只需将变量替换为您的列名称,并将其放置在您的“CHARINDEX('/',Fraction)> 0”为真的case语句部分中。
Declare @num varchar(50) = '1004 1/3'
-- Numerator
Select Left(Right(@num,Len(@num)-CharIndex(' ',@num)),CharIndex('/',Right(@num,Len(@num)-CharIndex(' ',@num)))-1)
-- Denominator
Select Right(Right(@num,Len(@num)-CharIndex(' ',@num)),Len(Right(@num,Len(@num)-CharIndex(' ',@num)))-CharIndex('/',Right(@num,Len(@num)-CharIndex(' ',@num))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.