Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper Case in Big Query

I have this sentence "i want to buy bananas" across column 'Bananas' in Big Query.

I want to get "I Want To Buy Bananas". How do I it? I was expecting PROPER(Bananas) function when I saw LOWER and UPPER but it seems like PROPER case is not supported?

DZ

like image 645
Daniel Zrůst Avatar asked Jul 15 '26 05:07

Daniel Zrůst


2 Answers

October 2020 Update:

BigQuery now support INITCAP function - which takes a STRING and returns it with the first character in each word in uppercase and all other characters in lowercase. Non-alphabetic characters remain the same.

So, below type of fancy-shmancy UDF is not needed anymore - instead you just use

#standradSQL
SELECT str, INITCAP(str) proper_str
FROM `project.dataset.table`

-- ~~~~~~~~~~~~~~~~~~

Below example is for BigQuery Standrad SQL

#standradSQL
CREATE TEMP FUNCTION PROPER(str STRING) AS (( 
  SELECT STRING_AGG(CONCAT(UPPER(SUBSTR(w,1,1)), LOWER(SUBSTR(w,2))), ' ' ORDER BY pos) 
  FROM UNNEST(SPLIT(str, ' ')) w WITH OFFSET pos
));
WITH `project.dataset.table` AS (
  SELECT 'i Want to buy bananas' str
)
SELECT str, PROPER(str) proper_str
FROM `project.dataset.table`  

result is

Row str                     proper_str   
1   i Want to buy bananas   I Want To Buy Bananas    
like image 115
Mikhail Berlyant Avatar answered Jul 20 '26 07:07

Mikhail Berlyant


I expanded on Mikhail Berlyant's answer to also capitalise after hypens (-) as I needed to use proper case for place names. Had to switch from the SPLIT function to using a regex to do this.

I test for an empty string at the start and return an empty string (as opposed to null) to match the behaviour of the native UPPER and LOWER functions.

CREATE TEMP FUNCTION PROPER(str STRING) AS (( 
  SELECT 
    IF(str = '', '',
      STRING_AGG(
        CONCAT(
          UPPER(SUBSTR(single_words,1,1)), 
          LOWER(SUBSTR(single_words,2))
        ), 
        '' ORDER BY position
      )
    )
  FROM UNNEST(REGEXP_EXTRACT_ALL(str, r' +|-+|.[^ -]*')) AS single_words
  WITH OFFSET AS position
));

WITH test_table AS (
  SELECT 'i Want to buy bananas' AS str
  UNION ALL
  SELECT 'neWCASTle upon-tyne' AS str
)

SELECT str, PROPER(str) AS proper_str
FROM test_table 

Output

Row str                     proper_str   
1   i Want to buy bananas   I Want To Buy Bananas  
2   neWCASTle upon-tyne     Newcastle Upon-Tyne
like image 23
Mark M Avatar answered Jul 20 '26 08:07

Mark M



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!