BigQuery: конвертировать повторяющиеся записи в повторяющиеся записи - PullRequest
0 голосов
/ 19 марта 2020

У меня есть таблица BigQuery, представленная этой JSON ( Запись повторного )

{
  "createdBy": [
    "foo",
    "foo"
  ],
  "fileName": [
    "bar1",
    "bar2"
  ]
}

, которую мне нужно преобразовать в Повторная запись

[
      {
        "createdBy": "foo",
        "fileName": "bar1"
      },
      {
        "createdBy": "foo",
        "fileName": "bar2"
      }
]

Чтобы сделать это преобразование, вы используете индекс 0 для каждого массива и создали первый объект, используйте индекс 1 для второго объекта, ...

Я выполнил этот вид преобразования используя UDF, но проблема связана с ограничениями BigQuery. Я не могу сохранить VIEW, который выполняет это преобразование:

No support for CREATE TEMPORARY FUNCTION statements inside views

После полного оператора для создания таблицы-примера и функции

CREATE TEMP FUNCTION filesObjectArrayToArrayObject(filesJson STRING)
  RETURNS ARRAY<STRUCT<createdBy STRING, fileName STRING>>
  LANGUAGE js AS """
    function filesObjectArrayToArrayObject_execute(files) {   
      var createdBy = files["createdBy"];
      var fileName = files["fileName"];
      var output = [];
      for(var i=0 ; i<createdBy.length ; i++) {
        output.push({ "createdBy" : createdBy[i], "fileName" : fileName[i] });
      }
      return output;
    }
    return filesObjectArrayToArrayObject_execute(JSON.parse(filesJson));
  """;

WITH sample_table AS (
  SELECT STRUCT<createdBy ARRAY<STRING>, fileName ARRAY<STRING>>(
    ["foo", "foo"],
    ["bar1", "bar2"]
  ) AS files
)

SELECT
  files AS filesOriginal,
  filesObjectArrayToArrayObject(TO_JSON_STRING(files)) AS filesConverted

FROM sample_table

Есть ли способ выполнить такую ​​же задачу с помощью собственных операторов BigQuery?

Обратите внимание:

  • Реальные данные имеют более 2 ключей, но они фиксированы в именах
  • Длина массива не фиксирована, может быть 0, 1, 10, 20, ...

1 Ответ

1 голос
/ 19 марта 2020

Ниже для BigQuery Standard SQL

#standardSQL
WITH sample_table AS (
  SELECT STRUCT<createdBy ARRAY<STRING>, fileName ARRAY<STRING>>(
    ["foo", "foo"],
    ["bar1", "bar2"]
  ) AS files
)
SELECT 
  ARRAY(
    SELECT STRUCT(createdBy, fileName) 
    FROM t.files.createdBy AS createdBy WITH OFFSET
    JOIN t.files.fileName AS fileName WITH OFFSET
    USING(OFFSET)
  ) files
FROM `sample_table` t  

с выводом

Row files.createdBy files.fileName   
1   foo             bar1     
    foo             bar2       
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...