Google bigquery 如何在BigQueryUDF主体中声明变量?
我试图在BigQuery上创建一个带有while循环的UDF函数,但我在文档中没有看到任何语法指南,这些指南专门针对这种情况,也没有在UDF主体中声明变量 上下文:我试图构建一个函数,将标题大小写应用于字符串 我试过:Google bigquery 如何在BigQueryUDF主体中声明变量?,google-bigquery,user-defined-functions,Google Bigquery,User Defined Functions,我试图在BigQuery上创建一个带有while循环的UDF函数,但我在文档中没有看到任何语法指南,这些指南专门针对这种情况,也没有在UDF主体中声明变量 上下文:我试图构建一个函数,将标题大小写应用于字符串 我试过: CREATE CREATE OR REPLACE FUNCTION mydataset.title_case(word STRING) as ( DECLARE i INT64; SET i = ARRAY_LENGTH(SPLIT(word, " &q
CREATE CREATE OR REPLACE FUNCTION mydataset.title_case(word STRING) as (
DECLARE i INT64;
SET i = ARRAY_LENGTH(SPLIT(word, " "));
...
);
但是,它不喜欢UDF主体中的DECLARE或SET。正确的语法是什么?关于如何在UDF中使用和设置变量的问题,您必须在代码开头声明和设置变量。然后,将其作为参数传递给UDF,语法如下:
DECLARE x ARRAY <String>;
SET x = (SELECT ARRAY_LENGTH(SPLIT(word, " ")) FROM `project_id.dataset.table`);
CREATE CREATE OR REPLACE FUNCTION mydataset.title_case(word STRING, x INT64) as (
#your function...
);
上下文:我试图构建一个函数,将标题大小写应用于字符串
与其直接回答这个问题,我倒不如谈谈我认为促使这个问题首先被提出的原因
从我在这里的经验来看,这是显而易见的,所以老年退休金计划经常问一些问题,这些问题实际上是为了帮助他们走错方向!在许多情况下,这是一种悲伤的经历,因为你知道你并没有对这样的人提供很好的帮助,而恰恰相反。我为自己多次参与其中而感到内疚,因为它并不总是真正清楚什么是真正的用例,所以并没有太多的选项可以帮助我,而不是像被问到的那个样回答确切的问题
我认为在这种情况下——上面的问题很好地暗示了真正的目的/用例——所以正如我已经说过的,我想回答它(用例)
在大多数情况下,您实际上不需要执行循环-您应该尝试以基于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
注意:以上只是一个(或两个)示例,说明了如何避免无效的基于光标的处理,而不是在SQL中执行“一体式”(基于集合的)转换。对这一点知道得很模糊,但还没来得及使用它。很高兴知道。因此,将变量声明放在函数之外,我担心调用函数时不会调用它们,以防函数是永久函数。我会试试看。实际上我改变了主意,选择了你的,因为它确实回答了实际问题。@Benjamin,你可以将UDf与SQL或JavaScript结合使用,这非常有用。我很高兴知道它有帮助。那太好了!我喜欢unnest在这里的用法,希望我曾经考虑过:)在第一个示例中,我没有得到的一点是使用| | inside string_agg()。第二个例子是,在我试着理解它之前,我需要再来一杯咖啡。谢谢
|
是一个串联运算符:o)-作为第二个示例-当然-休息一下,然后开始:o)好的,我现在知道了。我建议选择IF(REGEXP_包含(LAG(char)OVER(ORDER BY OFFSET)、r'\w')、LOWER(char)、UPPER(char))
添加LOWER()
,以确保它也能纠正已经大写或混乱的字符串。我正在使用您的解决方案,但我选择了另一个答案,因为它直接回答了开头的问题(即变量)。不过,我更喜欢您的SQL方法。我很高兴您注意到在此处使用LOWER的细微差别。:o)
#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