简体   繁体   English

从存储为字符串的数字中提取分数

[英]Extracting Fraction from Number stored as string

I've got a field in this database that stores number like so: 我在这个数据库中有一个字段,存储数字如下:

  • 80 1/4 80 1/4
  • 20 1/8 20 1/8
  • 20 20
  • 36 15/16 36 15/16
  • 44 1/8 44 1/8
  • 93 7/8 93 7/8
  • 89 1/8 89 1/8

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]

Link to demo on sqlfiddle. 链接到sqlfiddle上的demo。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM