Exécution de requêtes SQL de forme libre sur les tables des clean rooms

Vous pouvez permettre aux consommateurs d’exécuter des requêtes SQL de forme libre sur des ensembles de données sélectionnés dans une clean room à l’aide de l’API ou de l’UI de la clean room.

Requêtes en forme libre dans les API de clean rooms

Vous pouvez configurer une clean room pour permettre aux collaborateurs d’effectuer des requêtes sur des ensembles de données spécifiques depuis l’extérieur de la clean room. Les collaborateurs peuvent effectuer des requêtes de forme libre sur ces ensembles de données dans n’importe quel environnement où ils ont accès à la clean room, y compris Snowsight ou l’API Snowflake. Les ensembles de données de forme libre se comportent comme des vues standard en lecture seule qui peuvent être interrogées à l’aide de SQL, Python ou d’autres langues Snowflake prises en charge.

Politiques et soutien différentiel en matière de protection de la vie privée

Lorsque vous exposez des données de clean room pour des requêtes de forme libre, toutes les politiques de Snowflake Data Clean Rooms sont respectées. Les politiques Clean room (politiques de jointure, politiques de colonne) ne sont pas appliquées dans les requêtes de forme libre.

La confidentialité différentielle est et non appliquée aux données exposées à des requêtes de forme libre. Cela comprend à la fois Confidentialité différentielle dans Snowflake et Confidentialité différentielle des clean rooms.

Permettre des requêtes de forme libre

Important

Si une clean room a été créée avant juin 2025, le fournisseur doit installer le programme d’installation suivant afin de permettre les requêtes en forme libre dans cette clean room à l’aide de l’API :

USE ROLE SAMOOHA_APP_ROLE;
CALL samooha_by_snowflake_local_db.provider.patch_cleanroom($cleanroom_name,TRUE);
Copy

Fournisseur

Le fournisseur prend les mesures suivantes pour mettre les ensembles de données d’une clean room à la disposition des collaborateurs de la clean room à l’aide de requêtes en forme libre :

  1. Créez la clean room de la manière habituelle.

  2. Enregistrez et liez les ensembles de données dans la clean room de la manière habituelle. Notez qu’actuellement vos données doivent être enregistrées à l’aide de l’API ; vous ne pouvez pas enregistrer des vues dans l’UI de clean room et les utiliser pour des requêtes de forme libre. Vous devez appliquer les politiques d’agrégation, de jointure ou autres de Snowflake avant de partager vos données en dehors de la clean room.

  3. Appelez provider.enable_workflows_for_consumers pour permettre à des utilisateurs spécifiques d’accéder librement aux tables que vous spécifierez à l’étape suivante.

  4. Appelez provider.enable_datasets_for_workflow pour permettre aux utilisateurs de l’étape précédente d’accéder librement aux ensembles de données spécifiés ici.

  5. Ajoutez vos collaborateurs de manière standard en appelant provider.add_consumers.

  6. Publiez votre clean room.

  7. Si vous souhaitez révoquer l’autorisation d’interroger ces tables, vous pouvez le faire au niveau de l’utilisateur en appelant provider.disable_consumer_run_analysis ou provider.remove_consumers, au niveau de la vue en appelant library.unregister_objects ou library.unregister_db, ou en supprimant la clean room.

Si une clean room existe déjà et que les données sont enregistrées, vous pouvez simplement appeler provider.enable_workflows_for_consumers et provider.enable_datasets_for_workflow pour exposer les tables spécifiées aux utilisateurs spécifiés.

Le code suivant crée trois tables d’échantillons, crée une nouvelle clean room, établit des liens avec les tables et accorde aux collaborateurs de la clean room l’accès à ces tables sous forme de requêtes libres via la clean room.

----------------- Create sample data -----------------
USE ROLE MYROLE;
CREATE DATABASE freeform_db;

-- Create a table with an aggregation constraint.
CREATE OR REPLACE TABLE freeform_db.public.agg_constrained_table
  AS SELECT * FROM SAMOOHA_SAMPLE_DATABASE.DEMO.CUSTOMERS;

CREATE AGGREGATION POLICY freeform_db.public.agg_policy AS ()
  RETURNS AGGREGATION_CONSTRAINT ->
  AGGREGATION_CONSTRAINT(MIN_GROUP_SIZE => 5);

ALTER TABLE freeform_db.public.agg_constrained_table
  SET AGGREGATION POLICY freeform_db.public.agg_policy;

-- Create a table with a projection constraint.
CREATE OR REPLACE TABLE freeform_db.public.proj_constrained_table
  AS SELECT * FROM SAMOOHA_SAMPLE_DATABASE_FREEFORM.DEMO.CUSTOMERS;

CREATE OR REPLACE PROJECTION POLICY freeform_db.public.proj_policy AS ()
  RETURNS PROJECTION_CONSTRAINT ->
  PROJECTION_CONSTRAINT(ALLOW => false);

ALTER TABLE freeform_db.public.proj_constrained_table MODIFY COLUMN hashed_email
  SET PROJECTION POLICY freeform_db.public.proj_policy;

-- Create a table with a masking policy.
CREATE OR REPLACE TABLE freeform_db.public.masked_table
  AS SELECT * FROM SAMOOHA_SAMPLE_DATABASE_FREEFORM.DEMO.CUSTOMERS;

CREATE OR REPLACE MASKING POLICY freeform_db.public.masking_policy
  AS (val string) RETURNS STRING ->
  CASE
    WHEN current_account() IN ('DCR_PROVIDER_PP6') THEN VAL
    ELSE '*********'
  END;

ALTER TABLE freeform_db.public.masked_table MODIFY COLUMN hashed_email
  SET MASKING POLICY freeform_db.public.masking_policy;

----------------- Create and publish a clean room that supports -----------------
----------------- free-form queries against this data.          -----------------

-- Create the clean room. Nothing new here.
USE ROLE SAMOOHA_APP_ROLE;
SET cleanroom_name = 'freeform queries';
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.cleanroom_init($cleanroom_name, 'INTERNAL');

-- Link in the policy-protected tables from above. Nothing new here.
USE ROLE MYROLE;
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.register_db('freeform_db');
USE ROLE SAMOOHA_APP_ROLE;
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.link_datasets($cleanroom_name,
  ['freeform_db.public.agg_constrained_table',
  'freeform_db.public.proj_constrained_table',
  'freeform_db.public.masked_table']);

-- Grant the following consumer access to the tables specified next.
SET flow_name = freeform_sql;
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.enable_workflows_for_consumers($cleanroom_name,
  [$flow_name],
  ['<CONSUMER_LOCATOR>']);

-- Grant the consumer specified above access to the specified tables.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.enable_datasets_for_workflow($cleanroom_name,
  $flow_name,
  ['freeform_db.public.agg_constrained_table',
   'freeform_db.public.proj_constrained_table',
    'freeform_db.public.masked_table']);

-- Add collaborators and publish, in the standard way.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.add_consumers(
  $cleanroom_name, '<CONSUMER_LOCATOR>', '<ORG_NAME>.<CONSUMER_LOCATOR>');
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.set_default_release_directive(
  $cleanroom_name, 'V1_0', '0');
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.provider.create_or_update_cleanroom_listing(
  $cleanroom_name);
Copy

Consommateur

Une fois que le fournisseur a publié une clean room avec des flux de travail de forme libre sur SQL, les consommateurs ayant accès à cette clean room peuvent exécuter des requêtes sur les vues exposées.

  1. Installez la clean room de la manière habituelle. Il n’est pas nécessaire de créer des liens dans les données, le consommateur pouvant accéder directement à ses tables.

  2. Appelez consumer.get_provider_freeform_sql_views pour dresser la liste des vues SQL de forme libre disponibles pour le compte et le rôle actuels.

  3. Exécutez des requêtes standard sur le site SQL à partir des données. Les politiques du producteur seront appliquées aux données.

-- Install the clean room.
USE ROLE SAMOOHA_APP_ROLE;
SET cleanroom_name = 'freeform queries';

CALL samooha_by_snowflake_local_db.consumer.install_cleanroom($cleanroom_name, '<PROVIDER_LOCATOR>');

-- List free form views available in the clean room.
CALL samooha_by_snowflake_local_db.consumer.GET_PROVIDER_FREEFORM_SQL_VIEWS($cleanroom_name);

-- Run queries on the views
SELECT * FROM <PROJECTION_POLICY_VIEW_NAME>;
SELECT * FROM <MASKING_POLICY_VIEW_NAME>;
SELECT COUNT(hashed_email), age_band
  FROM <AGGREGATION_POLICY_VIEW_NAME> group by age_band;
Copy

Requêtes en forme libre dans les UI de clean rooms

Le modèle de requête SQL dans une clean room permet aux consommateurs d’écrire une forme libre SQL pour interroger les données de la clean room. Lors de l’utilisation du modèle de requête SQL, les requêtes des consommateurs doivent répondre à certaines exigences pour renvoyer des résultats. Ces exigences sont déterminées par la manière dont le fournisseur de données protège ses tables avec des politiques de confidentialité des données.

Lors de la création ou de la mise à jour d’une clean room dans l’UI, ajoutez le modèle de requête SQL à votre clean room et configurez-la comme décrit ci-dessous.

Fournisseur : Créez une clean room et définissez des politiques

  1. Créez une clean room ou modifiez une clean room existante, et spécifiez des tables ou des vues pour votre table.

  2. Les politiques de jonction spécifiées au cours du processus de création de la clean room sont ignorées lors de l’utilisation du modèle de requête SQL, mais respectées pour tous les autres modèles.

  3. Dans Configure Analysis & Query sélectionnez Horizontal » SQL Query.

  4. Dans la section des paramètres de SQL Query, définissez les propriétés suivantes :

    1. Sous Tables, sélectionnez les tables qui devraient être disponibles pour les collaborateurs de la clean room sous forme de requêtes libres. Par défaut, toutes les colonnes des tables sélectionnées peuvent être projetées et il n’est pas nécessaire d’appliquer des politiques d’agrégation. Pour contrôler les colonnes qui peuvent être projetées et celles qui doivent être agrégées, vous devez établir des politiques de colonnes dans la section suivante.

    2. Dans la section Column Policies, définissez les valeurs suivantes pour contrôler si ou comment vos colonnes peuvent être utilisées dans une requête :

      1. Aggregation policy columns: indiquez quelles colonnes doivent être agrégées pour apparaître dans les résultats de la requête. Si vous appliquez une politique d’agrégation à une colonne et qu’une colonne est utilisée dans une requête, les résultats doivent être agrégés. Toutes les colonnes annoncées ici seront ajoutées à la section Privacy settings.

      2. Projection policy columns: les colonnes dotées d’une politique de projection ne peuvent pas être projetées (c’est-à-dire incluses dans une SELECT instruction). Toutefois, les consommateurs peuvent filtrer ou effectuer une jointure sur une colonne à l’aide d’une politique de projection.

      3. Fully permitted columns: le consommateur peut SELECT, filtrer ou effectuer une jointure sur ces colonnes sans restriction (agrégation ou autre).

    3. La section Privacy settings dresse la liste de toutes les colonnes auxquelles une politique d’agrégation a été appliquée. La valeur Threshold indique combien d’entités doivent exister pour que cette valeur apparaisse dans les résultats. Par exemple, si vous avez fixé un seuil de 5 pour la colonne FIRST_NAME et que le nom Erasmus n’apparaît que 4 fois dans la table, toutes les lignes contenant Erasmus seront filtrées avant tout traitement (ainsi, par exemple, un COUNT(*) sur une telle table omettra les 4 lignes dont la taille du groupe est inférieure au seuil).

Consommateur : effectuez une requête de forme libre

  1. Rejoignez ou modifiez la clean room dans l’UI de clean room.

  2. Dans la section Configure Analysis & Query, choisissez les tables que vous utiliserez pour les requêtes en forme libre.

  3. Sélectionnez Finish pour enregistrer vos modifications.

  4. Pour exécuter une requête, sélectionnez Run dans la clean room avec le modèle de requête SQL et sélectionnez le modèle de requête SQL.

Sélectionnez les colonnes de jointure et de filtrage

Vous pouvez effectuer des jointures et des filtres sur n’importe quelle colonne qui a une politique ou qui est entièrement autorisée. Pour déterminer si une colonne peut être jointe ou utilisée dans un filtre :

  1. Dans la section Query Configurations, trouvez la vignette Tables.

  2. Utilisez la liste déroulante pour sélectionner une table. Vous pouvez effectuer des jointures et des filtres sur toutes les colonnes de la liste.

Sélectionnez les colonnes de projection

Les requêtes exécutées à l’aide des modèles de requête SQL ont des restrictions sur les colonnes qui peuvent être projetées (utilisées dans une instruction SELECT).

Pour déterminer si votre requête peut projeter une colonne :

  1. Dans la section Query Configurations, trouvez la vignette Tables.

  2. Utilisez la liste déroulante pour sélectionner une table.

  3. Recherchez les colonnes qui portent un label de politique de projection, ce qui signifie que vous ne pouvez pas les projeter. Vous pouvez projeter toutes les colonnes à l’exception de celles qui portent l’étiquette de la politique de projection.

Exigences en matière d’agrégation

Si le fournisseur a attribué une politique d’agrégation à une colonne, toutes les requêtes exécutées à l’aide du modèle de requête SQL doivent renvoyer des résultats agrégés.

Pour déterminer si votre requête doit regrouper les résultats :

  1. Dans la section Query Configurations, trouvez la vignette Tables.

  2. Utilisez la liste déroulante pour sélectionner une table.

  3. Recherchez les colonnes qui ont une étiquette de politique d’agrégation. S’il existe au moins une étiquette de politique d’agrégation, vous devez utiliser un agrégat dans votre requête.

Pour obtenir des instructions sur la manière d’écrire une requête réussie sur des données protégées par une politique d’agrégation, consultez :

Exigences graphiques

Pour que Snowflake puisse générer un graphique :

  • Le tableau des résultats doit inclure au moins une colonne de mesure (numérique) et une colonne de dimension (catégorie).

  • Le nom de la colonne de mesure doit avoir le préfixe ou le suffixe suivant (insensible à la casse) :

    • Préfixes de nom de colonne :

      • COUNT

      • SUM

      • AVG

      • MIN

      • MAX

      • OUTPUT

      • OVERLAP

    • Suffixe du nom de la colonne :

      • _OVERLAP

Snowflake génère un graphique en utilisant la première colonne de mesure éligible et la première colonne de dimension dans une table de résultats.

Limitations

  • Une clause ORDER BY n’a aucun effet sur la manière dont les résultats de l’analyse sont affichés.

Exemple de requêtes

Utilisez cette section pour mieux comprendre ce qu’une requête peut et ne peut pas inclure lors de l’exécution d’une analyse avec le modèle de requête SQL.

Requêtes sans fonction d’agrégation

Dans certaines circonstances, vous pouvez renvoyer des valeurs sans utiliser de fonction d’agrégation.

Autorisé

Non autorisé

SELECT gender, regions
  FROM TABLE sample_db.demo.customer
  GROUP BY gender, region;
Copy
SELECT gender, regions
  FROM TABLE sample_db.demo.customer;
Copy
Expressions de table communes (CTEs)

Autorisé

Non autorisé

WITH audience AS
  (SELECT COUNT(DISTINCT t1.hashed_email),
    t1.status
    FROM provider_db.overlap.customers t1
    JOIN consumer_db.overlap.customers t2
      ON t1.hashed_email = t2.hashed_email
    GROUP BY t1.status);

SELECT * FROM audience;
Copy
WITH audience AS
  (SELECT t1.hashed_email,
    t1.status
    FROM provider_db.overlap.customers quoted t1
    JOIN consumer_db.overlap.customers t2
      ON t1.hashed_email = t2.hashed_email
    GROUP BY t1.status)

SELECT * FROM audience
Copy
CREATE, ALTER, TRUNCATE

Une requête ne peut pas utiliser CREATE, ALTER ou TRUNCATE.

Requête avec jointures

Autorisé

SELECT p.education_level,
  c.status,
  AVG(p.days_active),
  COUNT(DISTINCT p.age_band)
  FROM  sample_database_preprod.demo.customers c
  INNER JOIN
  sample_database_preprod.demo.customers p
    ON  c.hashed_email = p.hashed_email
  GROUP BY ALL;
Copy
DATE_TRUNC

Autorisé

SELECT COUNT(*),
  DATE_TRUNC('week', date_joined) AS week
  FROM consumer_sample_database.audience_overlap.customers
  GROUP BY week;
Copy
Identificateurs avec guillemets

Autorisé

SELECT COUNT(DISTINCT t1.”hashed_email”)
  FROM provider_sample_database.audience_overlap."customers quoted" t1
  INNER JOIN
  consumer_sample_database.audience_overlap.customers t2
    ON t1."hashed_email" = t2.hashed_email;
Copy