Создать временную таблицу в каждом L oop и объединении после завершения L oop - PullRequest
1 голос
/ 01 февраля 2020

Используя стандартные функции сценариев BigQuery SQL, я хочу 1) создать временную таблицу для каждой итерации al oop и 2) объединить эти временные таблицы после завершения l oop. Я пробовал что-то вроде следующего:

DECLARE i INT64 DEFAULT 1;
DECLARE ttable_name STRING;

WHILE i < 10 DO
    SET ttable_name = CONCAT('temp_table_', CAST(i AS STRING));
    CREATE OR REPLACE TEMP TABLE ttable_name AS
        SELECT * FROM my_table AS mt WHERE mt.my_col = 1;
    SET i = i + 1;
END LOOP;

SELECT * FROM temp_table_*; -- wildcard table to union all results

Но я получаю следующую ошибку:

Превышено ограничение скорости: слишком много операций обновления таблицы для этой таблицы.

Как я могу выполнить sh эту задачу?

Ответы [ 3 ]

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

Ваш скрипт не работает так, как вы думаете!

Вместо записи в каждой итерации в отдельную таблицу с именем типа temp_table_N - вы фактически пишете в ту же самую временную таблицу с именем ttable_name - таким образом, ошибка Exceeded rate limits

BigQuery не разрешить использование переменных для имен объектов

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

Не создавайте новые таблицы. Добавьте к существующему с INSERT INTO или сохраните данные в переменной (если данных не слишком много), например:

DECLARE steps INT64 DEFAULT 1;
DECLARE table_holder ARRAY<STRUCT<steps INT64, x INT64, y ARRAY<INT64>>>;

LOOP 
  SET table_holder = (
    SELECT ARRAY_AGG(
      STRUCT(steps, 1 AS x, [1,2,3] AS y))
    FROM (SELECT '')
  );
  SET steps = steps+1;
  IF steps=30 THEN LEAVE; END IF;
END LOOP;

CREATE TABLE temp.results
AS
SELECT *
FROM UNNEST(table_holder)

Связано: { ссылка }

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

Вопрос задается / ОП здесь. Хотя я выбрал ответ @ felipe-hoffa, так как считаю, что это будет лучше для будущих читателей этого вопроса, я фактически пошел другим путем в решении своей проблемы:

BEGIN
    DECLARE i INT64 DEFAULT 1;


    CREATE OR REPLACE TEMP TABLE ttable AS
        SELECT
            CAST(NULL AS INT64) AS col1 -- cast NULL as the type of target col
            ,CAST(NULL AS FLOAT64) AS col2
            ,CAST(NULL AS DATE) AS col3;

    WHILE i < 10 DO

        -- overwrite `ttable` with its previous contents union'ed
        -- with new data results from current loop iteration
        CREATE OR REPLACE TEMP TABLE ttable AS
            SELECT mt.col1, mt.col2, mt.col3 FROM my_table AS mt WHERE mt.other_col = i
            UNION ALL
            SELECT * FROM ttable;

        SET i = i + 1;
    END LOOP;

    SELECT * FROM ttable; -- UNION'ed results

    DROP TABLE IF EXISTS ttable;

END;

Почему? Я считаю, что легче оставаться в «столовой стране», чем рисковать в «СТРУКТУРЕ / СТРЕЛКЕ».

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