I have a table which contains data like this:
MinFormat(int) MaxFormat(int) Precision(nvarchar)
-2 3 1/2
The
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)