Reputation: 501
In BigQuery standard SQL, I need to present a result of division as percentage with 2 decimal places, e.g. 21.23%. The only way I've been able to achieve this is by the doing the following:
ROUND
the result to 2 decimal placesCAST
it as a stringFORMAT
to add the percent characterFORMAT('%s%%', CAST(ROUND((val_1 / val_2) * 100, 2) AS STRING))
It feels like a workaround...
Is there a proper way of doing it? Primarily, I'd like to keep the output as a float, not a string.
Thanks!
Upvotes: 5
Views: 25119
Reputation: 11
as @nick winridge pointed out, there's an issue with less than 2 non-zero decimal places. This is a little hack that I added to fix that..
CREATE TEMP FUNCTION NUMFORMAT(number FLOAT64) AS (
CONCAT(REGEXP_EXTRACT(cast(((number + 0.000001) as string), r'\d*\.\d{2}'), ' %')
);
Upvotes: 1
Reputation: 1
I realise this is an old post but alexandre moraes's answer won't work if there aren't non-zeros beyond the 2nd decimal place in the argument passed to the function.
CREATE TEMP FUNCTION NUMFORMAT(number FLOAT64) AS (
CONCAT(REGEXP_EXTRACT(cast(number as string), r'\d*\.\d{2}'), ' %')
);
SELECT
NUMFORMAT(33.33212121),
NUMFORMAT(100.00000),
NUMFORMAT(100.00),
NUMFORMAT(100),
NUMFORMAT(100.00111)
gives result:
null values if less than 2 non-zero decimal places.
Upvotes: 0
Reputation: 4042
Your approach will work. However, I would advise you to create a TEMP FUNCTION. In case you are going to use it a couple of times, it will make your code look better and easier to read.
The syntax would be as follows:
#standardSQL
CREATE TEMP FUNCTION NUMFORMAT(number FLOAT64) AS (
CONCAT(REGEXP_EXTRACT(cast(number as string), r'\d*\.\d{2}'), ' %')
);
SELECT
NUMFORMAT(888888.999),
NUMFORMAT(123456.99),
NUMFORMAT(74185.009),
NUMFORMAT(-10.789)
Notice that I am assuming the data you want to format as percentiles is a FLOAT64. Although, if it is not a FLOAT64 you can change that in the function. And the output is:
If your percentiles are too high, you may also want to format the integer part of the number. The syntax would be as follows:
#standardSQL
CREATE TEMP FUNCTION NUMFORMAT(number FLOAT64) AS (
#CONCAT(REPLACE(REPLACE(REGEXP_REPLACE(FORMAT("%'.2f", number), r'([\d,]+).(\d+)', r'\1=\2'), ',', '.'), '=', ','),'%')
#CONCAT(REGEXP_EXTRACT(cast(number as string), r'\d*\.\d{2}'), ' %')
CONCAT(format("%'.2f", cast(REGEXP_EXTRACT(cast(number as string), r'\d*\.\d{2}') as float64)), '%')
);
SELECT
NUMFORMAT(888888.999),
NUMFORMAT(123456.99),
NUMFORMAT(74185.009),
NUMFORMAT(-10.789)
The output would be:
Upvotes: 6
Reputation: 1269743
Doesn't round()
do what you want?
SELECT ROUND((val_1 / val_2), 2)
Upvotes: 5