ML & AI/Data Engineering

BigQuery의 Procedural Language로 스크립트 작성하기

채얼음 2025. 2. 16. 23:58

1. BigQuery Procedural Language란?


BigQuery는 SQL 기반의 데이터 분석 도구이지만, 일반적인 SQL 쿼리만으로는 복잡한 로직을 처리하기 어려울 때가 있습니다. 이런 경우, BigQuery Procedural Language (SQL 스타일의 스크립트라고 생각하면 됩니다.) 를 활용하면 변수 선언, 조건문, 반복문 등을 사용하여 복잡한 로직을 보다 직관적으로 구현할 수 있습니다.

BigQuery에서 제공하는 Procedural Language를 사용하면 다음과 같은 작업이 가능합니다.
• 변수를 활용한 동적 SQL 실행
• 조건문 (IF, CASE)
• 반복문 (LOOP, WHILE, FOR)
• 예외 처리 (BEGIN ... EXCEPTION ... END)

이번 글에서는 실전에서 사용할 수 있는 BigQuery Procedural Language 스크립트를 소개하고, 코드 예시를 통해 이를 어떻게 활용할 수 있는지 살펴보겠습니다.

2. BigQuery Procedural Language의 기본 문법


BigQuery에서 Procedural Language를 사용하려면  서브쿼리만 사용하던 기존 SQL과는 달리, DECLARE, SET, BEGIN … END 등의 키워드를 사용할 수 있습니다.
기본적인 스크립트 구조는 다음과 같습니다.

DECLARE 변수명 데이터타입;
SET 변수명 = 값;

BEGIN
  -- 실행할 SQL 또는 조건문, 반복문
END;



예제를 통해 다양한 키워드를 하나씩 살펴보겠습니다.

3. 변수 선언 및 할당


BigQuery에서는 DECLARE 문을 사용하여 변수를 선언할 수 있습니다. 변수에는 정수, 문자열, 부동소수점 등 다양한 데이터 타입을 사용할 수 있으며, SET 문으로 값을 할당합니다.

DECLARE total_rows INT64;
SET total_rows = (SELECT COUNT(*) FROM `my_dataset.my_table`);

SELECT total_rows;



위 코드에서는 total_rows라는 변수를 선언하고, my_dataset.my_table의 행 개수를 저장한 후, 해당 값을 출력합니다.

4. 조건문 (IF, CASE)

4.1 IF 문 사용하기


BigQuery Procedural Language에서 IF 문을 활용하면 특정 조건에 따라 다른 SQL을 실행할 수 있습니다.

DECLARE row_count INT64;
SET row_count = (SELECT COUNT(*) FROM `my_dataset.my_table`);

BEGIN
  IF row_count > 1000 THEN
    SELECT '데이터가 너무 많습니다.' AS message;
  ELSE
    SELECT '데이터가 적절합니다.' AS message;
  END IF;
END;



이 코드는 my_dataset.my_table의 행 개수를 확인한 후, 1,000개 이상이면 경고 메시지를, 1,000개 미만이면 정상 메시지를 출력합니다.


4.2 CASE 문 사용하기


CASE 문을 사용하여 다중 조건을 처리할 수도 있습니다.

DECLARE category STRING;
SET category = 'A';

BEGIN
  CASE 
    WHEN category = 'A' THEN 
      SELECT 'Category A 선택' AS result;
    WHEN category = 'B' THEN 
      SELECT 'Category B 선택' AS result;
    ELSE 
      SELECT '알 수 없는 카테고리' AS result;
  END CASE;
END;


5. 반복문 (LOOP, WHILE, FOR)


반복문을 사용하면 특정 조건을 만족할 때까지 SQL을 실행할 수 있습니다.

5.1 LOOP 문 사용하기


반복문을 실행할 때는 LEAVE 문을 활용해 명시적으로 종료할 수 있습니다.

DECLARE counter INT64 DEFAULT 0;

BEGIN
  LOOP
    SET counter = counter + 1;

    IF counter >= 5 THEN
      LEAVE;
    END IF;

    SELECT counter;
  END LOOP;
END;



이 코드는 counter 값을 1씩 증가시키면서 5가 되면 반복을 종료합니다.

5.2 WHILE 문 사용하기


WHILE 문을 사용하면 특정 조건이 참일 동안 반복 실행할 수 있습니다.

DECLARE counter INT64 DEFAULT 1;

BEGIN
  WHILE counter <= 5 DO
    SELECT counter;
    SET counter = counter + 1;
  END WHILE;
END;


6. 예외 처리 (BEGIN ... EXCEPTION ... END)


예외 처리 (EXCEPTION)를 사용하면 오류가 발생했을 때 실행할 대체 로직을 정의할 수 있습니다.

DECLARE result INT64;

BEGIN
  BEGIN
    -- 존재하지 않는 테이블을 조회 (오류 발생)
    SET result = (SELECT COUNT(*) FROM `my_dataset.non_existent_table`);
  EXCEPTION WHEN ERROR THEN
    -- 오류 발생 시 실행할 대체 로직
    SELECT '테이블이 존재하지 않습니다.' AS error_message;
  END;
END;



이 코드는 non_existent_table 테이블이 존재하지 않을 경우 예외를 처리하여 "테이블이 존재하지 않습니다."라는 메시지를 출력합니다.

7. 예제: 테이블 데이터 정리하기


아래 예제는 특정 날짜 이전의 데이터를 삭제하는 스크립트입니다.

DECLARE threshold_date DATE;
SET threshold_date = DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY);

BEGIN
  DELETE FROM `my_dataset.my_table`
  WHERE created_at < threshold_date;

  SELECT '30일 이전 데이터가 삭제되었습니다.' AS message;
END;



이 코드는 현재 날짜 기준 30일 이전의 데이터를 삭제하는 기능을 수행합니다.

8. 마무리


BigQuery의 Procedural Language를 활용하면 SQL만으로는 구현하기 어려운 복잡한 로직을 보다 직관적으로 작성할 수 있습니다.

다음과 같은 기능을 사용할 수 있습니다.

✅ 변수 선언 및 할당
✅ 조건문 (IF, CASE)
✅ 반복문 (LOOP, WHILE, FOR)
✅ 예외 처리 (EXCEPTION)


실제로 업무에서 특정 기간 내의 데이터 백필 작업시 반복적으로 타겟 날짜를 지정한 후 쿼리를 실행하는 것이 아닌 Loop 문을 활용해 쿼리를 실행할 수 있었습니다.

다만, Procedural Language 사용 시 빅쿼리는 분산된 웨어하우스이므로 트랜잭션을 완전히 지원하지 않는다는 사실을 기억해야 합니다.
예외 발생시 전체 롤백이 불가능하므로, 코드 작성 시 오류 발생 가능성이 있는 경우 철저하게 대비해야 합니다.

이러한 점을 고려하여 적절한 사용 사례인 경우를 판단한 후, 이러한 기능을 적극적으로 활용하면 쿼리의 가독성을 높이고, 유지보수하기 쉬운 코드를 작성할 수 있습니다. 또한 보다 복잡한 데이터 처리 로직을 빅쿼리 내에서 모두 처리할 수 있다는 장점도 가져갈 수 있습니다.