Преобразование l oop с переменными в BigQuery SQL - PullRequest
0 голосов
/ 27 января 2020

У меня есть тысячи сценариев, которые включают l oop поверх набора данных и используют переменные для накопления. Например:

// assuming that 'ids' is populated from some BQ table
ids = [1, 2, 3, 4, 5]
var1 = "v1"   //initialize variable
var2 = "v2"   //initialize variable

for id in ids
    var1 = var2
    if (id > 2)
      var2 = var1 + "-" + item
    else
      var2 = id
    print(id, var1, var2)

Это приведет к выводу ниже:

1,v2,1
2,1,2
3,2,2-3
4,2-3,2-3-4
5,2-3-4,2-3-4-5

Несколько других факторов, которые следует учитывать:

  • Сценарий может включать n переменных.
  • Переменные могут действовать как аккумуляторы или могут просто иметь литералы.
  • Условие в l oop может быть более сложным, множественные вложенные if / else условия.
  • Скрипт может также иметь вложенный l oop, который будет l oop для n раз или до тех пор, пока не будет выполнено определенное условие.

Возможно ли его поддержка в BigQuery SQL? Я также открыт для BigQuery UDF, но UDF не поддерживает изменяемое состояние.

Кроме того, поскольку существуют тысячи таких сценариев, вместо того, чтобы делать это вручную, я хочу автоматизировать преобразование. Парсинг этих скриптов не проблема для меня, мне нужно только конвертировать это в эквивалент BigQuery SQL. Дайте мне знать, как я могу решить эту проблему.

Редактировать: Хотя я более склонен использовать SQL подход, но Сценарий BigQuery также кажется многообещающим вариантом .

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Мне удалось преобразовать SQL запрос для вышеупомянутого примера сценария:

with  t as
(select 1 as id union all
select 2 as id union all
select 3 as id union all
select 4 as id union all
select 5 as id)

select id, if(id = 1, 'v2', lag(var2) over(order by id)) var1, var2
from (
    select
      id,
      if(
        id > 2,
        string_agg(if(id > 1, concat('', '', cast(id as string)), null), '-') over (rows between unbounded preceding and current row),
        cast(id as string)
      ) var2
    from t
  )

И вот так я также могу преобразовать большинство сценариев в чистый SQL. Это просто построение модели вокруг, это более сложное дело, но, по крайней мере, я продвигаюсь вперед с ручными преобразованиями.

0 голосов
/ 28 января 2020

Мне удалось воспроизвести ваш скрипт, используя SQL UDF в BigQuery, я использовал Standard SQL вместо Legacy SQL, вы можете прочитать об этом подробнее здесь . Я хотел бы заявить, что UDF поддерживает JavaScript, и я считаю, что лучше написать его, используя его функциональность.

Я использовал эти фиктивные данные вместо объявления массива:

enter image description here

Ниже приведен сценарий, который я разработал, чтобы воспроизвести то, что вы достигли, используя свой код.

DECLARE VAR1 STRING DEFAULT 'v1';
DECLARE var2 STRING DEFAULT 'v2';

CREATE TEMPORARY FUNCTION test_v2 ( x1 string , x2 string,id INT64)
RETURNS STRING
LANGUAGE js AS """
var output= new Array(); 
i =0;
          while(i <= 5){
          x1=x2;
          if(i > 2) {
            x2 =x1 + " - " + i ;
            output.push(x2);

          } else{
                  x2 = i;
                  output.push(x2);
                } 
          i++;}return  output[id];
""";

CREATE TEMPORARY FUNCTION test_v1 ( x1 string , x2 string,id INT64)
RETURNS STRING
LANGUAGE js AS """
var output= new Array(); 
i =1;
output.push(x1);
          while(i <= 5){
          x1 = x2;
          if(i > 2) {
            x2 =x1 + " - " + i ;
            output.push(x1);

          } else{
                  output.push(x1);
                  x2 = i;
                } 
          i++;}return  output[id];
""";

SELECT ids,test_v1(var1,var2,ids) as v1, test_v2(var1,var2,ids) as var2 FROM `test-proj-261014.sample.ids` LIMIT 1000

Обратите внимание, что мне пришлось написать две разные функции, по одной для каждой строки var1 и var2 . Кроме того, массив начинается с позиции 1 в функции test_v1 .

Наконец, вывод был:

enter image description here

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...