SQL Server 2008 - 查询以获得分数格式的结果

时间:2016-04-11 12:53:57

标签: sql sql-server

我有一个包含这样的数据的表:

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

精度值只能是1 / 2,1 / 4,1 / 8,1 / 16,1 / 32,1 / 64。

现在我希望查询结果为 -

 -2
 -3/2 
 -1 
 -1/2 
  0 
  1/2 
  1 
  3/2  
  2 
  5/2 
  3

获取结果的任何查询如下?

想法是根据精度值,将最小边界(MinFomrat col值为整数)的结果创建为最大边界(MaxFormat Col值为整数)。

因此,在上面的例子中,值应该从-2开始,并根据精度值(1/2)生成下一个值,直到达到3

3 个答案:

答案 0 :(得分:7)

注意这只适用于Precision 1 / 1,1 / 2,1 / 4,1 / 8,1 / 16,1 / 32和1/64

DECLARE @t table(MinFormat int, MaxFormat int, Precision varchar(4))
INSERT @t values(-2, 3, '1/2')

DECLARE @numerator INT, @denominator DECIMAL(9,7)
DECLARE @MinFormat INT, @MaxFormat INT

-- put a where clause on this to get the needed row

SELECT @numerator   = 1,
       @denominator = STUFF(Precision, 1, charindex('/', Precision), ''),
       @MinFormat = MinFormat,
       @MaxFormat = MaxFormat
FROM @t


;WITH N(N)AS 
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f)
SELECT top(cast((@MaxFormat- @MinFormat)  / (@numerator/@denominator) as int) + 1) 
CASE WHEN val % 1 = 0 THEN cast(cast(val as int) as varchar(10))
     WHEN val*2 % 1 = 0 THEN cast(cast(val*2 as int) as varchar(10)) + '/2'
     WHEN val*4 % 1 = 0 THEN cast(cast(val*4 as int) as varchar(10)) + '/4'
     WHEN val*8 % 1 = 0 THEN  cast(cast(val*8 as int) as varchar(10)) + '/8'
     WHEN val*16 % 1 = 0 THEN cast(cast(val*16 as int) as varchar(10)) + '/16'
     WHEN val*32 % 1 = 0 THEN cast(cast(val*32 as int) as varchar(10)) + '/32'
     WHEN val*64 % 1 = 0 THEN cast(cast(val*64 as int) as varchar(10)) + '/64'
END
FROM tally
CROSS APPLY
(SELECT @MinFormat +(N-1) *(@numerator/@denominator) val) x

答案 1 :(得分:3)

对不起,现在我迟到了,但这是我的方法:

我实际上将它包装在TVF中并将其称为

SELECT * FROM dbo.FractalStepper(-2,1,'1/4');

或将其加入您的实际表格,如

SELECT *
FROM SomeTable
CROSS APPLY dbo.MyFractalSteller(MinFormat,MaxFormat,[Precision]) AS Steps

但无论如何,这就是代码:

DECLARE @tbl TABLE (ID INT, MinFormat INT,MaxFormat INT,Precision NVARCHAR(100));

--Inserting two examples
INSERT INTO @tbl VALUES(1,-2,3,'1/2')
                      ,(2,-4,-1,'1/4');

--Test with example 1, just set it to 2 if you want to try the other example
DECLARE @ID INT=1;

--If you want to get your steps numbered, just de-comment the tree occurencies of "Step"
WITH RecursiveCTE as
(
    SELECT  CAST(tbl.MinFormat AS FLOAT) AS RunningValue
           ,CAST(tbl.MaxFormat AS FLOAT) AS MaxF
           ,1/CAST(SUBSTRING(LTRIM(RTRIM(tbl.Precision)),3,10) AS FLOAT) AS Prec
           --,1 AS Step
    FROM @tbl AS tbl
    WHERE tbl.ID=@ID

    UNION ALL

    SELECT RunningValue + Prec
          ,MaxF 
          ,Prec
          --,Step + 1
    FROM RecursiveCTE
    WHERE RunningValue + Prec <= MaxF
)
SELECT RunningValue --,Step 
      ,CASE WHEN CAST(RunningValue AS INT)<>RunningValue 
            THEN CAST(RunningValue / Prec AS VARCHAR(10)) + '/' + CAST(CAST(1/Prec AS INT) AS VARCHAR(MAX))
            ELSE CAST(RunningValue AS VARCHAR(10))
       END AS RunningValueFractal
FROM RecursiveCTE;

结果

Value   ValueFractal
-2      -2
-1,5    -3/2
-1      -1
-0,5    -1/2
0        0
0,5      1/2
1        1
1,5      3/2
2        2
2,5      5/2
3        3

答案 2 :(得分:3)

我的其他人有点不同。我在分数上执行添加,最后简化了分数。

extends