上下文:我正在尝试构建一个函数以将标题大小写应用于字符串。
我不想直接回答这个问题,而是想先解决我认为促使这个问题被问到的原因
根据我在 SO 上的经验,很明显,OP 经常会提出问题,以帮助他们走错方向!在许多情况下,这是一种悲伤的经历,因为你明白你没有对这样的人提供很好的帮助,而是完全相反。多次参与其中让我感到内疚,因为并不总是很清楚真正的用例是什么,所以没有太多选择可以提供帮助,而不是回答被问到的确切问题
我认为在这种情况下 - 上面的问题很好地暗示了真正的目的/用例 - 所以正如我已经说过的,我想回答它(用例)
在大多数情况下,您实际上并不需要执行循环 - 您应该尝试以 sql 方式实现事物 - 基于集合!
所以,提示在下面的语句中
上下文:我正在尝试构建一个函数以将标题大小写应用于字符串。
title case函数的简单处理方法如下
#standardSQL
CREATE TEMP FUNCTION TitleCase(text STRING) AS ((
SELECT STRING_AGG(UPPER(SUBSTR(part, 1, 1)) || SUBSTR(part, 2), ' ' ORDER BY OFFSET)
FROM UNNEST(SPLIT(text, ' ')) part WITH OFFSET
));
SELECT text,
TitleCase(text) transformed_text
FROM `project.dataset.table`
您可以使用虚拟数据进行测试,如下例所示
#standardSQL
CREATE TEMP FUNCTION TitleCase(text STRING) AS ((
SELECT STRING_AGG(UPPER(SUBSTR(part, 1, 1)) || SUBSTR(part, 2), ' ' ORDER BY OFFSET)
FROM UNNEST(SPLIT(text, ' ')) part WITH OFFSET
));
WITH `project.dataset.table` AS (
SELECT 1 id, "google cloud platform" AS text UNION ALL
SELECT 2, "o'brian"
)
SELECT text,
TitleCase(text) transformed_text
FROM `project.dataset.table`
输出如下
Row text transformed_text
1 google cloud platform Google Cloud Platform
2 o'brian O'brian
如您所见,使用空格作为分隔符来分割文本的初始方法并不是最好的方法 - O'brian 没有得到 b 大写
要解决这个问题 - 您可以使用以下方法
#standardSQL
CREATE TEMP FUNCTION TitleCase(text STRING) AS ((
SELECT STRING_AGG(char, '' ORDER BY OFFSET)
FROM (
SELECT IF(REGEXP_CONTAINS(LAG(char) OVER(ORDER BY OFFSET), r'\w'), char, UPPER(char)) char, OFFSET
FROM UNNEST(SPLIT(text, '')) char WITH OFFSET
)
));
SELECT text,
TitleCase(text) transformed_text
FROM `project.dataset.table`
现在,当应用于相同的虚拟数据时 - 结果更合适
Row text transformed_text
1 google cloud platform Google Cloud Platform
2 o'brian O'Brian
注意:以上只是一个(或者更确切地说是两个)示例,说明如何避免基于光标的无效处理,而是在一个(基于集合的)回合中完成所有操作