Snowflake CEIL 函数 – 向上取整到下一个0.1公里。

huangapple go评论57阅读模式
英文:

Snowflake CEIL Function - round up to next 0.1 kilometer

问题

我有一个包含以米为单位的测量值的列。
我想要将它们四舍五入到下一个100米并返回为公里值。

特殊的情况是:如果原始值是“圆整”数(每100米递增),它应该向上四舍五入到下一个100米的递增(请参见下面示例中的第3行)。

示例:

meter_value     kilometer_value
1111            1.2
 111            0.2
1000            1.1

我认为我可以通过以下方式获得前两行:

ceil(meter_value/1000,1) as kilometer_value

我考虑的解决方案来处理第三行的特殊情况是始终添加1米:

ceil((meter_value+1)/1000,1) as kilometer_value

这似乎有点笨拙,是否有更好的方法/替代函数来实现这一目标?

英文:

I have a column containing measurement values in meters.
I want to round them up (ceil) them to the next 100m and return it as a km value.

Special thing is: if the original value is a "round" number (100m increment) it should be ceiled up to the next 100m increment (see line 3 in the example below).

Example:

meter_value     kilometer_value
1111            1.2
 111            0.2
1000            1.1

I think I can get the first two lines by doing:

ceil(meter_value/1000,1) as kilometer_value

The solution I thought of to fix the edge case in line three is to just add 1 meter always:

ceil((meter_value+1)/1000,1) as kilometer_value

It seems a bit clumsy, is there a better way/alternative function to archive this?

答案1

得分: 1

你可以检查是否可以被100整除,只有在可以整除时才加1:

ceil(((meter_value + iff(meter_value % 100 = 0, 1, 0))/1000), 1)

这样可以避免在允许小数部分的情况下,如果每次都加1,将导致在值为999.5时不准确。

英文:

You can check to see if it's divisible by 100 and only add one if it is:

ceil(((meter_value + iff(meter_value % 100 = 0, 1, 0))/1000), 1)

This will prevent situations where (if decimal parts are allowed) adding 1 to a value of 999.5 would not be accurate if adding one all the time.

答案2

得分: 1

Greg的答案很好,对我来说更容易阅读的方式是:

  • 除以100
  • 向下取整
  • 加1
  • 向上取整
  • 除以10
select
    column1 as METER_VALUE
    ,ceil(((METER_VALUE + iff(METER_VALUE % 100 = 0, 1, 0))/1000), 1) as GREG
    ,ceil(floor(METER_VALUE/100)+1)/10 as SIMEON
from values
    (1111)
    ,(111)
    ,(1000)
    ,(1)
    ,(0)
;
METER_VALUE GREG SIMEON
1,111 1.2 1.2
111 0.2 0.2
1,000 1.1 1.1
1 0.1 0.1
0 0.1 0.1

我们是否需要提到负值?我是说它是距离,所以是一个无方向的大小,对吗?

无论如何,对于负值,我们两种方法中的+1都会使边界情况出错。

实际上:

一旦你对添加1或0.1进行向下取整,如果先除以1000而不是100,就不需要再向上取整

因此,两种缩写形式可以是:

    ,ceil(floor(METER_VALUE/100)+1)/10 as VERSION_A
    ,(floor(METER_VALUE/100)+1)/10 as VERSION_B
    ,floor(METER_VALUE/1000,1)+0.1 as VERSION_C
英文:

Greg's answer is good, simpler to read to me would be to

  • divide by 100
  • floor
  • add 1
  • ceil
  • divide by 10
select
    column1 as meter_value
    ,ceil(((meter_value + iff(meter_value % 100 = 0, 1, 0))/1000), 1) as greg
    ,ceil(floor(meter_value/100)+1)/10 as simeon
from values
    (1111)
    ,(111)
    ,(1000)
    ,(1)
    ,(0)
;
METER_VALUE GREG SIMEON
1,111 1.2 1.2
111 0.2 0.2
1,000 1.1 1.1
1 0.1 0.1
0 0.1 0.1

do we want to mention negative values? I mean it distance, so it's a directionless magnitude, right?

anyway with negative value, both our methods the +1 forces the boundary case to be wrong.

Actually:

Once you have floored adding the 1 or 0.1 if you divide by 1000 vs 100 first, you don't need to ceil at all

thus two short forms can be:

    ,ceil(floor(meter_value/100)+1)/10 as version_a
    ,(floor(meter_value/100)+1)/10     as version_b
    ,floor(meter_value/1000,1)+0.1     as version_c

huangapple
  • 本文由 发表于 2023年2月7日 04:52:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75366468.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定