기본 다자간 협업을 해요

기본 다자간 협업을 해요


기능 — 일반 공개

현재 이들 리전에서 사용할 수 있어요.

정부 및 VPS 배포에서는 사용할 수 없어요.


출처: 문서

본문


소개

이 항목에서는 기본적인 다자간 협업을 만드는 단계를 안내해요. 템플릿과 데이터 오퍼링을 등록하는 방법, 협업 초기 버전에 데이터를 추가하는 방법, 그리고 협업이 만들어진 후 협업자가 리소스를 추가하는 방법을 보여줘요. 또한 협업에서 템플릿과 데이터 리소스를 사용하여 쿼리를 실행하는 방법도 보여줘요.

기본 클린 룸 협업 워크플로

여기 기본적인 다자간 클린 룸 협업 시나리오가 있어요.

협업 소유자는 협업 초기 구성에 표시하려는 템플릿이나 데이터 오퍼링을 등록해요.

소유자는 원하는 경우 참여 예정인 협업자에게 협업 초기 구성에 표시하려는 템플릿이나 데이터 오퍼링을 등록하도록 요청할 수 있어요. 그러면 협업자는 등록된 항목의 리소스 ID를 소유자에게 전달해요.

소유자는 협업을 만들어요. 협업은 협업자, 협업 역할, 그리고 협업 초기 버전에 있어야 하는 모든 리소스를 나열하는 협업 YAML 스펙으로 정의돼요.

  • 소유자는 EDIT를 호출하여 협업이 만들어진 후 협업자를 추가하거나 제거하고 협업자 역할을 변경하도록 요청할 수 있어요 (미리 보기 기능이에요). 이러한 변경 사항은 영향을 받는 협업자가 승인한 후에 적용돼요.

  • 협업이 만들어진 후에는 협업자의 협업 역할이 허용하는 경우 추가 리소스를 협업자가 추가할 수 있어요.

  • 협업이 다른 클라우드 호스팅 리전의 사용자와 데이터를 공유하는 경우, 공유자는 자신의 계정에서 Cross-Cloud Auto-Fulfillment를 활성화해야 해요.

협업자는 협업을 검토하고 참여해요.

그런 다음 협업자는 협업 역할에 따라 템플릿과 데이터 오퍼링 같은 추가 리소스를 협업에 연결할 수 있어요. 추가 리소스는 언제든지 협업에 추가할 수 있어요.

분석 실행자는 협업에서 자신에게 할당된 템플릿을 실행할 수 있어요. 이때 협업에서 사용할 수 있는 데이터를 사용해요. 분석 실행자가 분석 비용을 부담해요. 템플릿은 응답에서 쿼리 결과를 반환하도록 설계하거나 호출자 또는 다른 협업자에게 결과를 활성화하도록 설계할 수 있어요.

다음 섹션에서는 각 단계의 세부 사항을 설명해요.

협업 만들기

협업을 만들려면 모든 협업자와 그들의 협업 역할을 정의하는 협업 스펙을 설계해요.

협업이 만들어지는 즉시 리소스를 사용할 수 있게 하려면, 협업 소유자는 협업을 만들기 전에 해당 리소스를 등록하고 연결하고 리소스 ID를 협업 스펙에 포함해요.

소유자가 협업자의 리소스를 사용할 것으로 예상한다면, 소유자는 해당 사용자에게 자신의 리소스를 등록하고 리소스 ID를 소유자에게 제공하여 협업 스펙에 포함하도록 요청할 수도 있어요. 소유자는 협업 스펙에서 현재 연결된 리소스는 없지만 나중에 연결할 수 있는 위치도 표시해요.

그런 다음 소유자는 INITIALIZE를 호출하여 협업 만들기를 시작해요. 기본적으로 INITIALIZE는 소유자를 협업에 자동으로 참여시키기도 해요. 이는 비동기 프로세스이므로 소유자는 상태가 JOINED가 될 때까지 GET_STATUS를 호출해야 해요.

다음 스니펫은 협업을 만들고 참여하는 방법을 보여줘요.

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.INITIALIZE(
    $$
    api_version: 2.0.0
    spec_type: collaboration
    name: my_first_collaboration
    owner: alice
    collaborator_identifier_aliases:
      alice: example_com.acct_abc
      bob: another_example.acct_xyz
    analysis_runners:
      bob:
        data_providers:
          alice:
            data_offerings: [] -- alice has not provided data to bob, but can do so in the future.
          bob:
            data_offerings: [customers_v1]  -- bob has registered a data offering and made it available to himself.
        templates: []   -- No templates available yet for bob.
      alice:
        data_providers:
          alice:
            data_offerings: []
          bob:
            data_offerings: []
        templates: []
    $$,
    'APP_WH'            -- Use this warehouse for initialization.
  );                    --  XSMALL or SMALL warehouses are recommended for initialization.
  SET collaboration_name = 'my_first_collaboration';

  -- INITIALIZE automatically joins the owner. Check status until JOINED.
  CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.GET_STATUS($collaboration_name);

  -- Collaboration is visible here when it's joined.
  CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_COLLABORATIONS();

스크립트에 대한 참고 사항:

  • 협업은 alice와 bob이라는 별칭을 가진 두 명의 협업자로 구성돼요. 별칭을 사용하는 곳 어디에서나 전체 데이터 공유 ID를 사용할 수 있지만, 그렇게 하면 훨씬 사용자 친화적이지 않아요.

  • alice는 소유자예요.

  • alice와 bob 둘 다 분석 실행자예요.

  • alice와 bob은 서로에게 데이터 제공자예요.

  • 데이터 제공자라면 data_offerings 필드를 반드시 포함해야 해요. 이 필드는 채워져 있거나 비어 있을 수 있어요. 비어 있으면 현재 데이터 오퍼링이 없지만 나중에 추가할 수 있다는 뜻이에요.

  • alice는 bob이나 자신에게 데이터를 제공하지 않지만, 나중에 제공할 수 있어요 (14, 22행).

  • bob은 이미 데이터 오퍼링을 등록했고 초기 협업에서 자신에게 제공했어요 (16행).

  • bob은 alice에게 데이터를 제공하지 않지만, 나중에 제공할 수 있어요 (24행).

  • alice와 bob 모두 아직 사용 가능한 템플릿이 없지만, 나중에 할당할 수 있어요 (18, 25행). templates 필드는 분석 실행자에게 선택 사항이에요. 초기화 중에 이 필드를 생략해도 협업자는 나중에 이 분석 실행자에게 템플릿을 할당할 수 있어요.

협업에 리소스 연결하기



협력자는 자신의 협업 역할에 따라 리소스를 협업에 연결하거나, 협업에 연결한 리소스를 제거할 수 있어요. 리소스를 협업에 연결하는 단계는 두 가지가 있어요:

  1. 리소스 소유자가 리소스에 대한 리소스 정의 사양을 만들고 이를 사용하여 자신의 계정에 리소스를 등록해요. 계정의 기본 레지스트리에 리소스를 등록하거나 사용자 지정 레지스트리를 사용할 수 있어요.

  2. 협력자가 리소스를 협업에 연결해요. 리소스는 협업이 생성될 때 협업 생성에 사용되는 YAML 정의에 리소스 ID를 하드코딩하여 연결하거나, 협업이 생성되고 참여한 후 적절한 프로시저를 호출하여 리소스를 협업에 연결할 수 있어요.

리소스가 연결된 후에는 지정된 협력자가 사용할 수 있어요. 템플릿과 같은 일부 리소스 유형은 모든 협력자가 연결할 수 있지만, 데이터 오퍼링과 같은 다른 리소스는 데이터 제공자 협업 역할을 가진 사용자만 연결할 수 있어요. 단, 기여한 리소스가 협업에서 사용 가능해지려면 먼저 협업에 참여해야 한다는 점에 유의하세요.

다른 클라우드 호스팅 리전의 사용자와 데이터를 공유하는 경우, 공유자는 자신의 계정에서 Cross-Cloud Auto-Fulfillment를 활성화해야 해요.

리소스는 협업 사양에 따라 지정된 협력자에게만 제공돼요.

참고

기존 협업에 대한 업데이트(예: 리소스 연결 또는 제거)는 비동기적으로 이루어지며 완료하는 데 시간이 걸려요. 업데이트 상태를 확인하려면 VIEW_UPDATE_REQUESTS를 호출하세요. 리소스가 완전히 사용 가능해지기 전에 사용하면 일관되지 않은 동작이 발생할 수 있어요.

리소스는 버전 관리를 지원해요. 하지만 새 버전의 리소스를 생성해도 이전 버전이 협업에서 제거되지는 않아요. 리소스는 사용자가 제공한 이름과 버전(데이터 오퍼링의 경우 별칭도 포함)을 결합하여 고유하게 이름이 지정돼요.

협업에서 리소스를 사용하는 방법에 대해 자세히 알아보려면 리소스를 참조하세요.

협업 검토 및 참여

리소스를 공유하고 협업에서 분석을 실행하려면 협업에 참여해야 해요.

  • 생성자는 auto_join_warehouse가 제공된 경우 INITIALIZE를 호출할 때 자동으로 참여해요. auto_join_warehouse가 제공되지 않으면 생성자는 INITIALIZE가 완료된 후 JOIN을 호출해요.

  • 생성자가 아닌 사용자는 REVIEW를 호출한 다음 JOIN을 호출해요.

  • REVIEW는 협업과 해당 리소스에 대한 개요를 반환해요. REVIEW는 한 번만 호출할 수 있어요.

  • JOIN은 협업 Clean Room을 계정에 설치하고 협업에 참여해요.

  • INITIALIZE와 JOIN은 모두 완료하는 데 몇 분이 걸리는 비동기 프로시저예요. 각 단계가 완료되는 시점을 확인하려면 GET_STATUS를 호출해야 해요.

중요

계정의 클라우드 호스팅 리전이 협업 소유자의 리전과 다른 경우 REVIEW는 추가 비동기 설정 단계를 트리거해요. 설정이 완료되었음을 나타내는 성공 응답을 받을 때까지 REVIEW를 반복해서 호출하세요.

참여는 비동기 프로세스예요. 상태가 JOINED로 표시되는 시점을 확인하려면 GET_STATUS를 호출하세요.

분석 실행

협업에서 분석 실행자(analysis runner) 역할이 있으면 협업에서 공유된 데이터 소스에 대해 분석을 실행할 수 있어요.

협업은 두 가지 유형의 쿼리를 지원해요:

  • 템플릿 분석. 이 쿼리는 협업에 연결된 템플릿(템플릿화된 JinjaSQL 문)을 실행해요. 템플릿은 결과를 즉시 반환하는 분석 템플릿이거나, 지정된 참가자의 Snowflake 계정에 결과를 저장하는 활성화 템플릿일 수 있어요.

  • 자유 형식 SQL 쿼리. 데이터 제공자가 허용하는 경우, 협력자 자격 증명으로 로그인한 상태에서 SQL을 사용하여 지정된 데이터 오퍼링에 액세스할 수 있어요. 협업에서 노출하는 정규화된 뷰 이름에 액세스하여 Collaboration API 프로시저를 호출하지 않고 SQL 쿼리를 직접 실행해요.

분석 실행자가 분석 실행 비용을 부담해요.

협업 사양은 템플릿 실행, 결과 활성화, 자유 형식 SQL 쿼리 실행 가능 여부를 결정해요. 사용 가능한 데이터와 템플릿뿐만 아니라 본인의 기능도 협업 사양에 설명되어 있어요.

참고

데이터 소스의 열은 템플릿이나 사용자에게 노출될 때 새 이름을 가질 수 있어요. 소스 열이 어떻게 그리고 언제 이름이 바뀌는지 알아보려면 소스 열 이름 바꾸기를 참조하세요. 열 이름이 바뀌는 경우 템플릿과 사용자 제공 인수(예: 조인 열 이름)는 원래 이름이 아닌 최종 이름을 사용해야 해요.

이러한 모든 분석 유형에 대해 자세히 알아보려면 다음 섹션을 참조하세요.

템플릿에서 분석 실행

템플릿에서 분석을 실행하려면 실행할 수 있는 템플릿 목록과 사용할 수 있는 데이터 오퍼링 목록을 확인한 다음, 값을 개별 파라미터로 전달하거나 YAML 형식의 분석 사양으로 전달하면서 RUN을 호출해요.

실행 구성의 source_tables 필드에 전달하는 테이블은 템플릿의 source_table 파라미터를 채워요. 템플릿의 my_table 파라미터는 Snowflake Standard Edition에서 자체 데이터를 사용하는 경우가 아니면 채워지지 않거나 사용되지 않아요.

참고

리소스 설치는 비동기적으로 이루어져요. 템플릿을 방금 설치한 경우 실행 가능해지기까지 잠시 시간이 걸릴 수 있어요. 템플릿에 코드 스펙(code spec)이 포함되어 있으면 템플릿을 사용할 수 있을 때까지 추가 시간이 걸릴 수 있어요. 코드 스펙을 사용할 수 있는 시점을 확인하는 방법을 참고하세요.

다음 예제는 사용자가 액세스할 수 있는 데이터 오퍼링과 템플릿을 나열한 다음, sales_join_template 템플릿(VIEW_TEMPLATES에 나열되어 있다고 가정)을 사용하여 다섯 개의 명명된 인자를 템플릿에 전달하면서 분석을 실행해요.

-- See which data offerings are available.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_DATA_OFFERINGS($collaboration_name);

-- See which templates you can run.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_TEMPLATES($collaboration_name);

-- Pass in the arguments in analysis YAML format.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN(
  $collaboration_name,
  $$
    api_version: 2.0.0
    spec_type: analysis
    name: My_analysis
    description: Sales results Q2 2025
    template: sales_join_template

    template_configuration:
      view_mappings:
        source_tables:
          -  user1_alias.data_offering_v1.table_1
          -  user2_alias.another_data_offering_v1.table_2
      arguments:                                            -- The template defines conv_purchase_id and the other four arguments.
         conv_purchase_id: PURCHASE_ID                      -- You must examine a template to see which arguments it supports.
         conv_purchase_amount: PURCHASE_AMOUNT
         publisher_impression_id: IMPRESSION_ID
         publisher_campaign_name: CAMPAIGN_NAME
         publisher_device_type: DEVICE_TYPE
  $$ );

데이터에서 자유 형식 SQL 쿼리 활성화 및 실행

데이터 제공자는 분석 실행자(analysis runner)에게 자신의 데이터 오퍼링에 대해 임의의 SQL 쿼리를 실행할 수 있는 권한을 부여할 수 있어요. 즉, 분석 실행자는 템플릿을 호출하는 대신 데이터 오퍼링에 대해 임의의 SQL 쿼리를 직접 실행할 수 있어요.

자유 형식 SQL 쿼리에 대해 자세히 알아보려면 Free-form SQL queries를 참고하세요.

Standard Edition 사용 시 자체 데이터로 분석 실행

Standard Edition을 사용하는 경우 표준 방식으로 분석을 실행할 수 있어요. 하지만 다른 사용자와 공유하기 위해 데이터를 콜라보레이션에 연결할 수는 없어요. 자체 데이터셋을 템플릿에 전달하는 유일한 방법은 여기에서 설명하는 기법을 사용하는 거예요.

Snowflake Standard Edition의 콜라보레이션에서 자체 데이터를 사용하려면:

  1. REGISTER_DATA_OFFERING을 호출하여 데이터 오퍼링을 등록하세요.

  2. LINK_LOCAL_DATA_OFFERING을 호출하여 사용할 데이터를 콜라보레이션에 연결하세요. 다른 콜라보레이터는 로컬로 연결된 데이터를 보거나 액세스할 수 없어요.

  3. RUN을 호출할 때 데이터 오퍼링 ID를 사용하세요.

  • RUN의 파라미터화된 버전을 사용하는 경우 데이터 오퍼링 ID를 local_template_view_names 파라미터에 전달하세요.

  • RUN의 YAML 버전을 사용하는 경우 요청의 local_view_mappings.my_tables 스탠자에 데이터 오퍼링 ID를 제공하세요.

팁

local_template_view_names 및 local_view_mappings.my_tables는 템플릿의 my_table 파라미터를 채워요.

다음 예제는 실행 프로시저의 YAML 형식 버전을 사용하여 템플릿을 실행하는 방법을 보여줘요. 이 예제에는 LINK_LOCAL_DATA_OFFERING을 호출하여 채워지는 my_tables 필드가 포함되어 있어요.

-- See what data offerings are available. Your own local data will be listed here as well.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_DATA_OFFERINGS($collaboration_name);

-- Pass in the arguments in analysis YAML format.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN(
  $collaboration_name,
  $$
    api_version: 2.0.0
    spec_type: analysis
    name: my_analysis
    description: Cross-purchase results for Q4 2025
    template: mytemplate_v1

    template_configuration:
      view_mappings:
        source_tables:
          - ADVERTISER1.ADVERTISER_DATA_V1.CUSTOMERS
          - PUBLISHER.ADVERTISER_DATA_V1.CUSTOMERS
      local_view_mappings:
        my_tables:
          - PARTNER.MY_DATA_V1.MY_CUSTOMERS # Populate my_table array with my own table.
      arguments:  # Template arguments, as name: value pairs
         conv_purchase_id: PURCHASE_ID
         conv_purchase_amount: PURCHASE_AMOUNT
         publisher_impression_id: IMPRESSION_ID
         publisher_campaign_name: CAMPAIGN_NAME
         publisher_device_type: DEVICE_TYPE
  $$ );

결과 활성화

데이터 제공자와 콜라보레이션 사양이 허용하는 경우 분석 결과를 자신의 Snowflake 계정이나 지정된 콜라보레이터의 Snowflake 계정에 저장할 수 있어요. 템플릿은 결과를 활성화하거나 즉시 결과를 반환하며, 둘 다 수행하지는 않아요.

활성화에 대해 자세히 알아보려면 Activating query results를 참고하세요.

콜라보레이션 나가기 또는 삭제

  • 소유자가 아닌 사용자는 LEAVE를 호출하여 콜라보레이션을 나가요. 자신이 제공한 데이터 오퍼링은 콜라보레이션에서 제거돼요. 나간 후에는 콜라보레이션에 다시 합류할 수 없어요.

  • 콜라보레이션 소유자는 소유권을 양도할 수 없기 때문에 콜라보레이션을 나갈 수 없어요. 콜라보레이션 소유자는 TEARDOWN을 호출하여 모든 콜라보레이터를 위해 콜라보레이션을 삭제할 수 있어요.

두 프로세스 모두 비동기적으로 실행돼요. 상태를 모니터링하려면 GET_STATUS를 호출해야 하며, GET_STATUS에 상태가 LOCAL_DROP_PENDING으로 표시되면 LEAVE 또는 TEARDOWN을 다시 호출해야 해요.

소유자가 콜라보레이션을 삭제한 후에도 여전히 멤버였던 모든 콜라보레이터는 LOCAL_DROP_PENDING 상태를 확인하고, 자신의 계정에서 Clean Room 애플리케이션과 콜라보레이션 메타데이터를 제거하려면 LEAVE를 한 번 호출해야 해요. 자세한 내용은 LEAVE를 참고하세요.

예제

다음 SQL 예제는 기본 콜라보레이션을 만들고 실행하는 방법을 보여줘요:

양자 콜라보레이션 예제

다음 예제는 양자 콜라보레이션을 보여줘요. 한 당사자(이름이 “alice”)는 콜라보레이션 생성자이자 자신과 “bob”을 위한 데이터 제공자이며 분석 실행자예요. “bob”은 자신과 “alice”를 위한 데이터 제공자이자 분석 실행자이기도 해요.

이 예제는 다음 작업을 보여줘요:

  • 콜라보레이션 만들기.

  • 템플릿 및 데이터 오퍼링 등록.

  • 콜라보레이션 생성 시 템플릿과 데이터 오퍼링 연결.

  • 콜라보레이션 참여.

  • 기존 콜라보레이션에 추가 리소스 연결.

  • 분석 실행.

이 예제를 실행하려면 Snowflake Data Clean Rooms가 설치된 별도의 계정 두 개가 필요해요.


파일을 다운로드하여 Snowflake 계정에 업로드하거나, Snowsight를 사용하여 두 개의 별도 계정에 있는 워크시트에 예제 코드를 복사하여 붙여넣을 수 있습니다.

소스 SQL 파일을 다운로드한 다음, Snowflake Data Clean Rooms가 설치된 두 개의 별도 계정에 업로드하세요:

-- Basic Snowflake Collaboration Data Clean Rooms example.
-- This file represents user "alice" in a two-collaborator clean room example.

-- Run this worksheet in a Snowflake account with access to the latest version of
-- Snowflake Data Clean Rooms.

-- This file demonstrates the following actions:
-- * How to register a template and a dataset
-- * How to create a collaboration with pre-registered resources.
-- * How to add a template to a collaboration that has already been created, and the
--   template approval flow.
-- * How to run an analysis.

-- This scenario involves two collaborators: bob and alice
-- bob and alice each submits one data source
-- bob and alice are data providers for themselves and each other
-- bob submits one template that only alice can use
-- alice submits one template that they can both use, and one template that only alice can use

-- For more information, read docs.snowflake.com/user-guide/cleanrooms/overview

USE WAREHOUSE APP_WH;
USE ROLE SAMOOHA_APP_ROLE;

-- Secondary roles must be disabled to call link_data_offerings.
USE SECONDARY ROLES NONE;

CREATE DATABASE IF NOT EXISTS ALICE_DB;
CREATE SCHEMA IF NOT EXISTS ALICE_DB.ALICE_SCH;
CREATE OR REPLACE TABLE ALICE_DB.ALICE_SCH.ALICE_DATA AS SELECT * FROM samooha_sample_database.demo.customers LIMIT 100;

-- Register a data offering to use in the initial collaboration definition.
CALL samooha_by_snowflake_local_db.registry.register_data_offering(
    $$
    api_version: 2.0.0
    spec_type: data_offering
    version: v1
    name: <alice data offering name>
    datasets:
     - alias: customer_list
       data_object_fqn: ALICE_DB.ALICE_SCH.ALICE_DATA
       object_class: custom
       allowed_analyses: template_only
       schema_and_template_policies:
         hashed_email:
           category: join_standard
           column_type: hashed_email_b64_encoded
         status:
           category: passthrough
    $$
    );

-- Save the ID of the registered data offering.
SET alice_data_offering_id = '<data_offering_id>';

CALL samooha_by_snowflake_local_db.registry.view_registered_data_offerings();

-- Register a template to use in the initial collaboration definition.
CALL samooha_by_snowflake_local_db.registry.register_template(
$$
api_version: 2.0.0
spec_type: template
name: alice_only_template
version: <version_number>
type: sql_analysis
description: A test template
template:
  SELECT t1.status, COUNT(*)
    FROM IDENTIFIER( {{ source_table[0] }} ) AS t1
    JOIN IDENTIFIER( {{ source_table[1] }} ) AS t2
    ON t1.hashed_email_b64_encoded = t2.hashed_email_b64_encoded
    GROUP BY t1.status;
$$);

-- Save the ID of the registered template.
SET my_template_id = '<alice_only_template_id>';
CALL samooha_by_snowflake_local_db.registry.view_registered_templates();

-- Create a collaboration with the previously registered template and data offering.
-- The collaboration supports two collaborators, with aliases alice (this account) and bob.
-- Owner: alice
-- Analysis runners:
--   * alice, using her own data, and the template you created and registered earlier.
--   * bob, with no listed templates or data.
-- Data providers:
--   * alice and bob, for alice
--   * alice and bob, for bob
-- Resources added: The template and data offering alice registered earlier.
-- You will add more templates and data offerings to these users later. Only these
-- users are invited to the collaboration, and no additional users can be added later.
-- Replace the <...> placeholders with the appropriate values.
-- Account data sharing IDs are -- SELECT CURRENT_ORGANIZATION_NAME() || '.' || CURRENT_ACCOUNT_NAME();
CALL samooha_by_snowflake_local_db.collaboration.initialize(
$$
api_version: 2.0.0
spec_type: collaboration
name: my_first_collaboration_1_0
owner: alice
collaborator_identifier_aliases:
  alice: <my account data sharing ID>
  bob: <bob account data sharing ID>
analysis_runners:
  bob:
    data_providers:
      alice:
        data_offerings:
        - id: <alice data offering ID>
      bob:
        data_offerings: []
  alice:
    data_providers:
      alice:
        data_offerings:
        - id: <alice data offering ID>
      bob:
        data_offerings: []
    templates:
    - id: <alice only template ID>
$$,
'APP_WH'
);
SET collaboration_name = '<collaboration_name>';

-- INITIALIZE automatically joins the owner. Check status until JOINED.
CALL samooha_by_snowflake_local_db.collaboration.get_status($collaboration_name);

-- Collaboration is visible here when the owner has joined.
CALL samooha_by_snowflake_local_db.collaboration.view_collaborations();

-- Auto-approve any template requests from other collaborators that affect you.
CALL samooha_by_snowflake_local_db.collaboration.set_configuration(
  $collaboration_name,
  'TEMPLATE_AUTO_APPROVAL',
  'true'
);

-- SWITCH TO collaborator to join the collaboration and add a template
-- The template will be auto-approved.

-- Create a new template.
CALL samooha_by_snowflake_local_db.registry.register_template(
    $$
    api_version: 2.0.0
    spec_type: template
    name: both_use_template
    version: 2026_01_12_V1
    type: sql_analysis
    description: test_description
    template:
      select * from identifier({{ source_table[0] }}) limit 5;

    $$
);
SET both_use_template = '<template ID>';

-- Ask to add the template to the collaboration. You must ask bob, because you're
-- including bob in the sharing list. When you share a template with yourself,
-- you auto-approve it.
CALL samooha_by_snowflake_local_db.collaboration.add_template_request(
  $collaboration_name,
  $both_use_template,
  ['alice', 'bob']   -- List of collaborators who can use this template.
  );

-- SWITCH TO bob to approve the request. Request wasn't approved automatically
-- because bob didn't enable auto-approve.

-- See if bob approved the request.
CALL samooha_by_snowflake_local_db.collaboration.view_update_requests($collaboration_name);

-- See what the collaboration spec looks like now, after all the resource updates.
-- Collaboration updates are asynchronous, so if all changes that you made aren't present,
-- wait a minute or two, and then try again.
CALL samooha_by_snowflake_local_db.collaboration.view_collaborations() ->>
  SELECT "COLLABORATION_SPEC" FROM $1 WHERE "SOURCE_NAME" = $collaboration_name;

-- SWITCH TO bob to add a data offering.

-- Run an analysis.
-- Tables are scoped as <data_offering_id>.<alias>.
CALL samooha_by_snowflake_local_db.collaboration.view_data_offerings(
  $collaboration_name
);
SET $bob_data_offering = '<bob data offering ID>';

CALL samooha_by_snowflake_local_db.collaboration.view_templates(
  $collaboration_name
);

-- Run bob's template.
-- Replace the placeholders with your variables.
CALL samooha_by_snowflake_local_db.collaboration.run(
  $collaboration_name,
    $$
    api_version: 2.0.0
    spec_type: analysis
    description: <optional description of the analysis>
    template: '<alice_only_template>'
    template_configuration:
      view_mappings:
        source_tables:
          - '<alice_data_offering_view_name>'
          - '<bob_data_offering_view_name>'
    $$
  );

-- Multi-step cleanup process to delete the collaborations.
-- Doesn't delete registered resources.
CALL samooha_by_snowflake_local_db.collaboration.teardown($collaboration_name);
CALL samooha_by_snowflake_local_db.collaboration.get_status($collaboration_name);

-- When get_status reports LOCAL_DROP_PENDING, call teardown again.
CALL samooha_by_snowflake_local_db.collaboration.teardown($collaboration_name);

DROP DATABASE ALICE_DB;
-- Basic Snowflake Collaboration Data Clean Rooms example.
-- This file represents user "bob" in a two-collaborator clean room example.

-- Run this worksheet in a Snowflake account with access to the latest version of
-- Snowflake Data Clean Rooms.

-- This file  demonstrates the following actions:
-- * Joining a collaboration
-- * Registering and adding a template and a data offering to an existing collaboration.
-- * Running an analysis.

-- For more information, read docs.snowflake.com/user-guide/cleanrooms/overview

USE WAREHOUSE APP_WH;
USE ROLE SAMOOHA_APP_ROLE;

-- Secondary roles can't be active when calling join or link_data_offering.
USE SECONDARY ROLES NONE;

-- Create sample data.
CREATE DATABASE IF NOT EXISTS BOB_DB;
CREATE SCHEMA IF NOT EXISTS BOB_DB.BOB_SCH;
CREATE OR REPLACE TABLE BOB_DB.BOB_SCH.BOB_DATA AS SELECT * FROM samooha_sample_database.demo.customers_2 LIMIT 100;

-- See which collaborations you are invited to, or have joined.
CALL samooha_by_snowflake_local_db.collaboration.view_collaborations();

-- Use SOURCE_NAME column value from the response to view_collaborations().
SET collaboration_name = '<collaboration name>';

-- Use OWNER_ACCOUNT column value from the response to view_collaborations().
SET collaborator_data_sharing_id = '<collaborator_id>';

-- Review and join the collaboration.
-- Joining is asynchronous, so you must call get_status until the status is JOINED before
-- you can perform actions on the collaboration.
CALL samooha_by_snowflake_local_db.collaboration.review($collaboration_name, $collaborator_data_sharing_id);
CALL samooha_by_snowflake_local_db.collaboration.join($collaboration_name);
CALL samooha_by_snowflake_local_db.collaboration.get_status($collaboration_name);

-- Demonstrate the auto-approve flow.
-- Alice enabled auto-approve on her account, so this request will
-- be auto-approved, and the template will be added immediately.

-- Create a template.
CALL samooha_by_snowflake_local_db.registry.register_template(
    $$
    api_version: 2.0.0
    spec_type: template
    name: auto_approve_template
    version: V1
    type: sql_analysis
    description: test_description
    template:
      SELECT * FROM IDENTIFIER({{ source_table[0] }}) LIMIT 10;
    $$
);
SET auto_approve_template = '<template_id>';

CALL samooha_by_snowflake_local_db.collaboration.add_template_request($collaboration_name, $auto_approve_template, ['alice', 'bob']);
CALL samooha_by_snowflake_local_db.collaboration.view_update_requests($collaboration_name);

-- SWITCH TO other account and request adding a template, and then come back to approve the request.

-- You haven't enabled template auto-approve, so you must approve the request before the template is added.
CALL samooha_by_snowflake_local_db.collaboration.view_update_requests($collaboration_name);
CALL samooha_by_snowflake_local_db.collaboration.approve_update_request(
  $collaboration_name,
  '<request_ID>'
);

-- SWITCH TO bob to see the request status.

-- Register your own data offering.
CALL samooha_by_snowflake_local_db.registry.register_data_offering(
    $$
    api_version: 2.0.0
    spec_type: data_offering
    version: v3
    name: bob_data
    datasets:
     - alias: my_customer_list
       data_object_fqn: BOB_DB.BOB_SCH.BOB_DATA
       object_class: custom
       allowed_analyses: template_only
       schema_and_template_policies:
         hashed_email:
           category: join_standard
           column_type: hashed_email_b64_encoded
         status:
           category: passthrough
    $$
);

SET my_data_id = '<data offering id>';

-- Share the data offering with yourself and alice.
CALL samooha_by_snowflake_local_db.collaboration.link_data_offering(
  $collaboration_name,
  $my_data_id,
  ['alice', 'bob']
);

CALL samooha_by_snowflake_local_db.collaboration.view_data_offerings(
  $collaboration_name
);

-- View templates that you can use in this collaboration. You can run only templates that list you in the
-- SHARED_WITH column.
CALL samooha_by_snowflake_local_db.collaboration.view_templates($collaboration_name);

-- Run an analysis with your template.
CALL samooha_by_snowflake_local_db.collaboration.run(
    $collaboration_name,
    $$
    api_version: 2.0.0
    spec_type: analysis
    description: <optional description of the analysis>
    template:  '<both_use_template>'
    template_configuration:
      view_mappings:
        source_tables:
          -  '<my_data_offering_view_name>'
          -  '<bob_data_offering_view_name>'
    $$
);

-- SWITCH TO other account to run an analysis.

-- Try running an analysis using alice-only template.
-- This will fail, because you aren't listed as an analysis
-- runner for this template.
CALL samooha_by_snowflake_local_db.collaboration.run(
  $collaboration_name,
  $$
  api_version: 2.0.0
  spec_type: analysis
  description: <optional description of the analysis>
  template: '<alice_only_template>'
  template_configuration:
    view_mappings:
      source_tables:
        - '<my_data_offering_view_name>'
        - '<bob_data_offering_view_name>'
  $$
);

-- Clean up resources.
DROP DATABASE BOB_DB;

단일 파티 콜라보레이션 예시

이 예시는 테스트용 계정이 하나만 있는 경우 콜라보레이션을 생성하고 사용하는 방법을 보여줍니다.

이 예시는 데이터 오퍼링과 템플릿으로 콜라보레이션을 생성한 다음, 콜라보레이션이 생성된 후 다른 데이터 오퍼링과 템플릿을 추가하고 분석을 실행하는 방법을 보여줍니다.

파일을 다운로드하여 Snowflake 계정에 업로드하거나, Snowsight를 사용하여 워크시트에 예제 코드를 복사하여 붙여넣을 수 있습니다.

소스 SQL 파일을 다운로드한 다음, Snowflake Data Clean Rooms가 설치된 Snowflake 계정에 업로드하세요:

-- ============================================================================
-- Single-user Collaboration Clean Rooms demo
-- ============================================================================
-- This example demonstrates a basic Snowflake Data Clean Rooms collaboration
-- using a single Snowflake account and a single role: SAMOOHA_APP_ROLE.
-- One user acts as the owner, data provider, and analysis runner.
--
-- The user creates two sample datasets, registers two data offerings and two
-- templates, then creates a collaboration with one data offering and one template each.
--  After the collaboration is created, the user links the remaining data offering and
-- template, then runs an analysis with each template. Finally, the code
-- cleans up all resources used.
--
-- For more information, see:
--   docs.snowflake.com/user-guide/cleanrooms/overview
--   docs.snowflake.com/user-guide/cleanrooms/spec-reference
-- ============================================================================

-- ============================================================================
-- SETUP: Create sample databases and data.
-- ============================================================================

USE ROLE SAMOOHA_APP_ROLE;
USE WAREHOUSE APP_WH;

-- You can't use secondary roles with most collaboration procedures.
USE SECONDARY ROLES NONE;

CREATE DATABASE IF NOT EXISTS DEMO_DB;
CREATE SCHEMA IF NOT EXISTS DEMO_DB.DATA_SCH;

-- Dataset 1: 300 rows from CUSTOMERS.
CREATE OR REPLACE TABLE DEMO_DB.DATA_SCH.CUSTOMERS_1 AS
  SELECT HASHED_EMAIL, STATUS, AGE_BAND
  FROM SAMOOHA_SAMPLE_DATABASE.DEMO.CUSTOMERS
  LIMIT 300;

-- Dataset 2: 300 rows from CUSTOMERS_2.
CREATE OR REPLACE TABLE DEMO_DB.DATA_SCH.CUSTOMERS_2 AS
  SELECT HASHED_EMAIL, STATUS, AGE_BAND
  FROM SAMOOHA_SAMPLE_DATABASE.DEMO.CUSTOMERS_2
  LIMIT 300;

-- ============================================================================
-- Register data offerings and templates.
-- ============================================================================

-- Register the first data offering.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_DATA_OFFERING(
  $$
  api_version: 2.0.0
  spec_type: data_offering
  version: V1
  name: customers_1
  datasets:
    - alias: customers_1
      data_object_fqn: DEMO_DB.DATA_SCH.CUSTOMERS_1
      object_class: custom
      allowed_analyses: template_only
      schema_and_template_policies:
        hashed_email:
          category: join_standard
          column_type: hashed_email_b64_encoded
        status:
          category: passthrough
        age_band:
          category: passthrough
  $$
);

SET data_offering_1_id = '<data_offering_1_id>';

-- Register the second data offering.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_DATA_OFFERING(
  $$
  api_version: 2.0.0
  spec_type: data_offering
  version: V1
  name: customers_2
  datasets:
    - alias: customers_2
      data_object_fqn: DEMO_DB.DATA_SCH.CUSTOMERS_2
      object_class: custom
      allowed_analyses: template_only
      schema_and_template_policies:
        hashed_email:
          category: join_standard
          column_type: hashed_email_b64_encoded
        status:
          category: passthrough
        age_band:
          category: passthrough
  $$
);

SET data_offering_2_id = '<data_offering_2_id>';

-- Register a template that joins two tables on hashed_email and returns
-- a count of rows grouped by age_band.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: age_band_count
version: V1
type: sql_analysis
description: Joins two tables on hashed_email and returns age_band with row counts.
template:
  SELECT t1.age_band, COUNT(t1.age_band) AS age_band_count
    FROM IDENTIFIER({{ source_table[0] }}) AS t1
      JOIN IDENTIFIER({{ source_table[1] }}) AS t2
      ON t1.hashed_email_b64_encoded = t2.hashed_email_b64_encoded
    GROUP BY t1.age_band;
$$
);

SET age_band_template_id = '<age_band_template_id>';

-- Register a template that joins two tables on hashed_email and returns
-- a count of rows grouped by status.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: status_count
version: V1
type: sql_analysis
description: Joins two tables on hashed_email and returns status with row counts.
template:
  SELECT t1.status, COUNT(t1.status) AS status_count
    FROM IDENTIFIER({{ source_table[0] }}) AS t1
      JOIN IDENTIFIER({{ source_table[1] }}) AS t2
      ON t1.hashed_email_b64_encoded = t2.hashed_email_b64_encoded
    GROUP BY t1.status;
$$
);

SET status_template_id = '<status_template_id>';

-- Confirm that both data offerings and both templates are registered.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.VIEW_REGISTERED_DATA_OFFERINGS();
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.VIEW_REGISTERED_TEMPLATES();

-- ============================================================================
-- Create the collaboration with one data offering and one template.
-- ============================================================================

-- Replace <account_data_sharing_id> with:
--   SELECT CURRENT_ORGANIZATION_NAME() || '.' || CURRENT_ACCOUNT_NAME();
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.INITIALIZE(
  $$
  api_version: 2.0.0
  spec_type: collaboration
  name: single_user_demo
  owner: me
  collaborator_identifier_aliases:
    me: <account_data_sharing_id>
  analysis_runners:
    me:
      data_providers:
        me:
          data_offerings:
            - id: <data_offering_1_id>
      templates:
        - id: <age_band_template_id>
  $$,
  'APP_WH'
);

SET collaboration_name = '<collaboration_name>';

-- Verify that the owner has joined. Repeat until status is JOINED.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.GET_STATUS($collaboration_name);

-- ============================================================================
-- Link the remaining data offering and template into the collaboration.
-- ============================================================================

-- Link the second data offering.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.LINK_DATA_OFFERING(
  $collaboration_name, $data_offering_2_id, ['me']);

-- Add the status_count template to the collaboration.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.ADD_TEMPLATE_REQUEST(
  $collaboration_name, $status_template_id, ['me']);

-- ============================================================================
-- List resources and run analyses.
-- ============================================================================

-- List all data offerings in the collaboration.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_DATA_OFFERINGS($collaboration_name);

-- List all templates in the collaboration.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.VIEW_TEMPLATES($collaboration_name);

-- Run the age_band_count template.
-- Replace placeholders with the template name/version and view names from
-- VIEW_TEMPLATES and VIEW_DATA_OFFERINGS.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN(
  $collaboration_name,
  $$
  api_version: 2.0.0
  spec_type: analysis
  description: Count matching rows grouped by age_band.
  template: '<age_band_count_template_name_and_version>'
  template_configuration:
    view_mappings:
      source_tables:
        - '<data_offering_view_1>'
        - '<data_offering_view_2>'
  $$
);

-- Run the status_count template.
-- Replace placeholders with the template name/version and view names from
-- VIEW_TEMPLATES and VIEW_DATA_OFFERINGS.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN(
  $collaboration_name,
  $$
  api_version: 2.0.0
  spec_type: analysis
  description: Count matching rows grouped by status.
  template: '<status_count_template_name_and_version>'
  template_configuration:
    view_mappings:
      source_tables:
        - '<data_offering_view_1>'
        - '<data_offering_view_2>'
  $$
);

-- ============================================================================
-- CLEANUP: Delete the collaboration, registered resources, and sample data.
-- ============================================================================

-- Teardown is a multi-step process. Call TEARDOWN, then wait for GET_STATUS
-- to report LOCAL_DROP_PENDING, then call TEARDOWN again.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.TEARDOWN($collaboration_name);
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.GET_STATUS($collaboration_name);

-- When GET_STATUS reports LOCAL_DROP_PENDING, call TEARDOWN again to complete.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.TEARDOWN($collaboration_name);

-- Unregister the data offerings and templates from the default registry.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.UNREGISTER_DATA_OFFERING($data_offering_1_id);
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.UNREGISTER_DATA_OFFERING($data_offering_2_id);
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.UNREGISTER_TEMPLATE($age_band_template_id);
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.UNREGISTER_TEMPLATE($status_template_id);

-- Drop the sample database.
DROP DATABASE IF EXISTS DEMO_DB;

더 알아보기 (Learn more)