甲骨文显示号码
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
无论哪种方式,您都可以轻松地将逻辑放入函数中。
我只看过正数,non-zero 数字;如果您需要处理零数或负数,则需要 a little bit more work.
我们需要获取一些非常大的数字并以这样的缩写方式显示它们:
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 |
无论哪种方式,您都可以轻松地将逻辑放入函数中。
我只看过正数,non-zero 数字;如果您需要处理零数或负数,则需要 a little bit more work.