SQL Server 2008 - Query to get result in fraction format

后端 未结 3 1033
挽巷
挽巷 2021-01-14 05:55

I have a table which contains data like this:

MinFormat(int)  MaxFormat(int)  Precision(nvarchar)
   -2              3             1/2

The

3条回答
  •  暖寄归人
    2021-01-14 06:29

    Mine is a bit different others. I perform the addition on fraction and at the end, simplified the fraction.

    -- This solution uses CTE
    -- it breaks the @min, @max number into fraction
    -- perform the addition in terms of fraction
    -- at result, it attemp to convert the fraction to simpliest form
    
    declare @min        int,
        @max        int,
        @step       varchar(10),
        @step_n     int,    -- precision step numerator portion
        @step_d     int -- precision step denominator portion
    
    select  @min    = -2,
        @max    = 3,
        @step   = '1/16'
    
    select  @step_n = left(@step, charindex('/', @step) - 1),
        @step_d = stuff(@step, 1, charindex('/', @step), '')
    
    ; with rcte as
    (
        -- Anchor member
        select  n = @min,   -- numerator
            d = 1,      -- denominator
            v = convert(decimal(10,5), @min)
    
        union all
    
        -- Recursive member
        select  n = case when ( (r.n * @step_d) + (r.d * @step_n) ) % @step_d = 0 
                 and  (r.d * @step_d) % @step_d = 0
                 then ( (r.n * @step_d) + (r.d * @step_n) ) / @step_d
                 else (r.n * @step_d) + (r.d * @step_n)
                 end, 
            d = case when ( (r.n * @step_d) + (r.d * @step_n) ) % @step_d = 0
                 and  (r.d * @step_d) % @step_d = 0
                 then (r.d * @step_d) / @step_d
                 else (r.d * @step_d)
                 end,
            v =  convert(decimal(10,5), ((r.n * @step_d) + (r.d * @step_n)) / (r.d * @step_d * 1.0))
        from    rcte r
        where   r.v < @max
    )
    select  *,
        fraction    = case  when    n = 0
                    then    '0'
                    when    coalesce(d2, d) = 1
                    then    convert(varchar(10), coalesce(n2, n))
                    else    convert(varchar(10), coalesce(n2, n)) + '/' + convert(varchar(10), coalesce(d2, d))
                    end
    from    rcte r
        cross apply -- use to simplify the fraction result
        (
            select  n2 = case when n % 32 = 0 and d % 32 = 0 then n / 32
                      when n % 16 = 0 and d % 16 = 0 then n / 16
                      when n % 8 = 0 and d % 8 = 0 then n / 8
                      when n % 4 = 0 and d % 4 = 0 then n / 4
                      when n % 2 = 0 and d % 2 = 0 then n / 2
                      end,
                d2 = case when n % 32 = 0 and d % 32 = 0 then d / 32
                      when n % 16 = 0 and d % 16 = 0 then d / 16
                      when n % 8 = 0 and d % 8 = 0 then d / 8
                      when n % 4 = 0 and d % 4 = 0 then d / 4
                      when n % 2 = 0 and d % 2 = 0 then d / 2
                      end
        ) s
    order by v
    option (MAXRECURSION 0)
    

提交回复
热议问题