Эффективный способ написать функцию в BigQuery - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть функция, которую я хочу оптимизировать:

CREATE OR REPLACE FUNCTION <project>.<dataset>.<function_name>( tv1 STRING, tv2 STRING) <br>
RETURNS STRING <br>
AS ( <br>
CASE
when lower(tv1) = 'val1' then '11' <br>
when lower(tv1) = 'val2' then 'ABC1' <br>
when lower(tv1) = 'val3' then 'XYZ5' <br>
when lower(tv2) = 'val4' then 'MyVal' <br>
when lower(tv2) = 'val5' then 'HisVal' <br>
else 'nothing' <br>
end <br>
); <br>

Здесь я могу избежать использования lower() в каждом предложении и сделать это один раз INSIDE самой функции. Я не хочу вызывать нижнюю функцию с помощью вызова lower() извне. Как я могу сделать это внутри самой функции?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

Ниже для BigQuery Standard SQL

CREATE TEMP FUNCTION test( tv1 STRING, tv2 STRING)
RETURNS STRING AS ((
  SELECT CASE 
    WHEN tv1 = 'val1' THEN '11'
    WHEN tv1 = 'val2' THEN 'ABC1'
    WHEN tv1 = 'val3' THEN 'XYZ5'
    WHEN tv2 = 'val4' THEN 'MyVal'
    WHEN tv2 = 'val5' THEN 'HisVal'
    ELSE 'nothing'
  END
  FROM UNNEST([LOWER(tv1)]) tv1, UNNEST([LOWER(tv2)]) tv2
));   

Как вы можете видеть, это устраняет необходимость в использовании LOWER в каждом и каждом «предложении», но все же требует использования LOWER один раз для tv1 и tv2

1 голос
/ 20 февраля 2020

Если вам удобнее, вы также можете использовать JavaScript для определения своих функций (JavaScript Структура UDF ), но, как отметил @Mikhail, вам нужно преобразовать в строчные буквы оба tv1 и tv2 хотя бы один раз для каждой переменной:

CREATE TEMP FUNCTION test(tv1 STRING, tv2 STRING)
RETURNS STRING
LANGUAGE js
AS """

  tv1 = tv1.toLowerCase();
  tv2 = tv2.toLowerCase();

  if(tv1 == "val1") return "11";
  if(tv1 == "val2") return "ABC1";
  if(tv1 == "val3") return "XYZ5";
  if(tv2 == "val4") return "MyVal";
  if(tv2 == "val5") return "HisVal";

  return "nothing";

""";
...