【问题标题】:Google BigQuery IF/While LoopGoogle BigQuery IF/While 循环
【发布时间】:2020-05-26 04:14:45
【问题描述】:
DECLARE var1 INT64;
SET var1=(select * from abc.xyz);
{SOME OTHER OPERATIONS}

错误:超出可变配额。

为了解决这个问题,我想运行一个批处理进程,其中计数来自 abc.xyz 表,第一批只处理 50000 条记录,结果存储在临时表中。在下一次迭代中,循环处理另外 50000 个并将它们添加到临时表中。

How can this be done in google bigquery?

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    错误是因为limit size for a variable is 1MB

    关于处理批次的循环。您可以使用以下 SQL 作为参考:

    DECLARE offset_ INT64 DEFAULT 1; -- OFFSET starts in 1 BASED on ROW NUMBER ()
    DECLARE limit_ INT64 DEFAULT 500; -- Size of the chunks to be processed
    DECLARE size_ INT64 DEFAULT 7000; -- Size of the data (used for the condition in the WHILE loop)
    
    -- Table to be processed. I'm creating this new temporary table to use it as an example
    CREATE TEMPORARY TABLE IF NOT EXISTS data_numbered AS (
    
      SELECT *, ROW_NUMBER() OVER()  row_number
        FROM (SELECT * FROM `bigquery-public-data.stackoverflow.users` LIMIT 7000)
    );
    
    -- WHILE loop
    WHILE offset_ < size_ DO
    
        IF offset_ = 1 THEN -- OPTIONAL, create the temporary table in the first iteration
    
          CREATE OR REPLACE TEMPORARY TABLE temp_table AS (    
            SELECT * FROM data_numbered
              WHERE row_number BETWEEN offset_ AND offset_ + limit_ - 1 -- Use offset and limit to control the chunks of data 
           );
    
        ELSE
    
         -- This is the same query as above.
         -- Each iteration will fill the temporary table
         -- Iteration
         -- 501 - 1000
         -- 1001 - 1500
         -- ...
    
          INSERT INTO temp_table (
            SELECT * FROM data_numbered WHERE row_number BETWEEN offset_ AND offset_ + limit_ - 1 -- -1 because BETWEEN is inclusive, so it helps to avoid duplicated values in the edges
          );
    
        END IF;
    
        -- Adjust the offset_ variable
        SET offset_ = offset_ + limit_;
    
    END WHILE;
    
    

    制作此循环的挑战之一是您不能在 LIMIT 和 OFFSET 子句中使用变量。因此,我使用 ROW_NUMBER() 创建了一个列,我可以用它来处理 WHERE 子句:

     WHERE row_number BETWEEN offset_ AND offset_ + limit_
    

    如果您想了解更多关于 ROW_NUMBER() 的信息,我建议您查看this SO answer

    最后,如果您想使用这种方法,请考虑一些注意事项,例如脚本是Beta feature,并且可能是quota issues,具体取决于您将数据插入临时表的频率。另外,由于查询在每次迭代中都会发生变化,第一次运行时,它没有缓存,bytes_processed 将是表的 number_of_iterations*byte_size

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 2023-03-22
      • 2015-05-19
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2012-08-04
      • 2012-12-02
      • 2013-06-09
      相关资源
      最近更新 更多