Oracle 11g - 如何计算最小值或最大值范围内的数字值

时间:2017-05-04 17:10:12

标签: oracle oracle11g

我需要帮助来解决我的问题,请。

我有一张这样的表:

 ID    Number
|6    |20.90  |
|7    |45.00  |
|8    |52.00  |
|9    |68.00  |
|10   |120.00 |
|11   |220.00 |
|12   |250.00 |

第一个范围是 0 - 20.90 。 当值为一半时,值id为最大范围。

  • 当我获得价值20.91时,我想得到" ID = 6"。
  • 如果值为31.00,我想得到" ID = 6"
  • 如果值是 33.95,我希望得到" ID = 7"。
  • 如果值为44.99,我想获得ID = 7

我怎么做?是否有能够满足我需要的功能?

2 个答案:

答案 0 :(得分:1)

如果您希望记录的编号最接近您的输入,则可以使用:

select *
from   (
        select   *
        from     mytable
        order by abs(number - my_input_number), id
       )
where  rownum < 2

内部查询选择所有记录,但按照输入编号中的距离对它们进行排序。可以使用number - my_input_number计算此距离。但这可能是负面的,所以我们采取绝对值。这个结果不输出;它只是用来订购。因此,距离较小的记录将首先出现。

现在我们只需要第一条记录,这就是外部查询对典型的Oracle保留字rownum的作用:它表示最终结果集的每条记录的序列号(1,2 ,3,......)。 where子句将有效地过滤掉我们不想看到的所有记录,只留下一个(距离最小)。

正如mathguy在评论中建议的那样,order by现在还有第二个值可供选择,以防输入值恰好位于两个最接近的记录之间的中点。在这种情况下,将选择id值最低的记录。

答案 1 :(得分:0)

这是分析函数功能的一个很好的例证:

with mytable ( id, value ) as (
       select  6,  20.90 from dual union all
       select  7,  45.00 from dual union all
       select  8,  52.00 from dual union all
       select  9,  68.00 from dual union all
       select 10, 120.00 from dual union all
       select 11, 220.00 from dual union all
       select 12, 250.00 from dual
     ),
     inputs ( x ) as (
       select   0.00 from dual union all
       select  20.91 from dual union all
       select  31.00 from dual union all
       select  33.95 from dual union all
       select  44.99 from dual union all
       select  68.00 from dual union all
       select  32.95 from dual union all
       select 400.11 from dual
     )
  -- End of test data (not part of the solution). SQL query begins BELOW THIS LINE
select   val as x, new_id as closest_id
from     (
           select id, val,
                  last_value(id ignore nulls) over (order by val desc) as new_id
           from   (
                    select id, (value + lead(value) over (order by value))/2 as val
                      from mytable
                    union all
                    select null, x
                      from inputs
                  )
         )
where    id is null
order by x  --  if needed
;

<强>输出

X       CLOSEST_ID
------  ----------
     0           6
 20.91           6
    31           6
 32.95           6
 33.95           7
 44.99           7
    68           9
400.11          12