1

我在这个数据库中有一个字段存储数字,如下所示:

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

我正在尝试将这些转换为完整的小数,以便我可以将它们相加。我一直在尝试通过从数字中提取小数,将其转换为小数,然后将其添加到整数来做到这一点。我在提取分子时遇到了一些重大问题。分母已使用以下方法提取:

CASE WHEN CHARINDEX('/',Fraction) > 0 THEN RIGHT(Faction,(LEN(Fraction) - (CHARINDEX('/',Fraction)))) ELSE NULL END AS [Denominator]

我不确定这是否是最有效的方法,但它似乎有效。

我试图用这种方法把分子拉出来:

CASE WHEN Charindex('/', Fraction) > 0 THEN LEFT(RIGHT(Fraction, Len(Fraction) - Charindex(' ',Fraction)), CHARINDEX('/',Fraction) - 1) ELSE NULL END AS [Numerator]

但这只是给了我分数本身。我不确定 SQL 是否在 LEFT 中存在 RIGHT 问题,因为它似乎没有做任何事情,或者更有可能是我的代码搞砸了。

有人有想法么?

谢谢!

4

4 回答 4

2

您几乎做对了:您正在计算LEFT错误传递的长度。您需要考虑空间的位置。

代替

CHARINDEX('/',Fraction) - 1

长度应该是

CHARINDEX('/',Fraction) - CHARINDEX(' ',Fraction) - 1

整体表达式应如下所示:

CASE WHEN Charindex('/', Fraction) > 0 THEN LEFT(RIGHT(Fraction, Len(Fraction) - Charindex(' ',Fraction)), CHARINDEX('/',Fraction) - CHARINDEX(' ',Fraction) - 1) ELSE NULL END AS [Numerator]

链接到 sqlfiddle 上的演示。

于 2013-01-15T15:13:17.560 回答
1

这应该有效。我已经将 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
于 2013-01-15T15:16:03.580 回答
0

您可以尝试以下方法:

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
于 2013-01-15T15:13:17.683 回答
0

只需复制将变量替换为您的列名,并将其放在您的“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))))
于 2013-01-15T15:16:33.907 回答