甲骨文显示号码

Oracle Display Number

我们需要获取一些非常大的数字并以这样的缩写方式显示它们:

2113546998.37   --> 21.37B
15481063.31  --> 15.31M

等等。我认为 Oracle 没有这样做的方法。希望得到一些帮助。

您可以使用 log 和 power 来操纵和解释该值;将它四舍五入到最接近的 'large number' 括号的小数位:

round(your_number / power(10, 3 * floor(log(10, your_number) / 3)), 2)

然后获取要附加的字母,例如:

case 3 * floor(log(10, your_number) / 3)
  when 0 then null when 3 then 'K' when 6 then 'M'
  when 9 then 'B' when 12 then 'T' when 15 then 'Q'
end

依此类推,但如果你变得更大,你将不得不决定如何区分千万亿和五亿。

使用一些扩展示例数据,完整查询:

select your_number,
  round(your_number / power(10, 3 * floor(log(10, your_number) / 3)), 2)
  ||
  case 3 * floor(log(10, your_number) / 3)
    when 0 then null when 3 then 'K' when 6 then 'M'
    when 9 then 'B' when 12 then 'T' when 15 then 'Q'
    else 'x'
  end as result
from your_table
order by your_number

获得

YOUR_NUMBER RESULT
123.456789 123.46
1234.56789 1.23K
12345.6789 12.35K
123456.789 123.46K
1234567.89 1.23M
15481063.31 15.48M
123456789 123.46M
2113546998.37 2.11B
123456789123 123.46B
123456789123456 123.46T

所以你的两个原始值得到 2.11B 和 15.48M,而不是 21.37B 和 15.31M 如您的问题所示 - 但正如评论中指出的那样,仅保持精度的两个极端并没有真正意义。这样做是可能的,当然 - floor 而不是 round,并附加原始小数部分 - 但它似乎不太可能是你真正的意思,我假设 21 vs 2 和小数部分都是将问题放在一起的错误.

虽然您可能不想将它应用于较小的数字 - 'K' 可能不太常见? - 如果是这样,您可以使用另一个 case 表达式来决定。例如:

select your_number,
  case
    when log(10, your_number) < 6
    then to_char(round(your_number, 2))
    else
      round(your_number / power(10, 3 * floor(log(10, your_number) / 3)), 2)
      ||
      case 3 * floor(log(10, your_number) / 3)
        when 6 then 'M' when 9 then 'B' when 12 then 'T' when 15 then 'Q'
        else 'x'
      end
  end as result
from your_table
order by your_number
YOUR_NUMBER RESULT
123.456789 123.46
1234.56789 1234.57
12345.6789 12345.68
123456.789 123456.79
1234567.89 1.23M
15481063.31 15.48M
123456789 123.46M
2113546998.37 2.11B
123456789123 123.46B
123456789123456 123.46T

无论哪种方式,您都可以轻松地将逻辑放入函数中。

db<>fiddle

我只看过正数,non-zero 数字;如果您需要处理零数或负数,则需要 a little bit more work.