Les données e-commerce GA4 dans BigQuery se répartissent entre deux structures : un RECORD ecommerce au niveau transaction et un REPEATED RECORD items au niveau produit. Comprendre les deux — et leur relation — est le point de départ de toute analyse des achats depuis les données GA4 brutes.
Le RECORD ecommerce
Le RECORD ecommerce stocke les données au niveau transaction. C’est un simple RECORD imbriqué (pas un tableau repeated), donc accéder aux champs nécessite la notation pointée plutôt que UNNEST :
| Champ | Description |
|---|---|
ecommerce.transaction_id | ID de commande — votre identifiant d’achat canonique |
ecommerce.purchase_revenue | Chiffre d’affaires dans la devise configurée pour l’événement |
ecommerce.purchase_revenue_in_usd | Chiffre d’affaires converti en USD au moment de la collecte |
ecommerce.shipping_value | Coût de livraison |
ecommerce.tax_value | Montant de la taxe |
ecommerce.total_item_quantity | Nombre total d’items dans la transaction |
Le RECORD ecommerce n’est significatif que pour les événements e-commerce — purchase, refund, begin_checkout, add_payment_info. Pour les autres événements, ces champs sont null.
SELECT event_name, ecommerce.transaction_id, ecommerce.purchase_revenue, ecommerce.purchase_revenue_in_usd, ecommerce.total_item_quantityFROM `project.analytics_123456789.events_*`WHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260131' AND event_name = 'purchase'Le REPEATED RECORD items
Le champ items est un REPEATED RECORD — un tableau — où chaque élément représente un produit dans la transaction. Un achat de trois produits distincts produit un événement purchase avec trois éléments dans items.
| Champ | Description |
|---|---|
items.item_id | SKU ou identifiant du produit |
items.item_name | Nom du produit |
items.item_brand | Marque |
items.item_category | Catégorie principale |
items.item_category2 à item_category5 | Niveaux de la hiérarchie de catégories |
items.price | Prix unitaire |
items.quantity | Quantité de cet item |
items.coupon | Code coupon appliqué |
items.discount | Montant de la remise |
items.affiliation | Attribution magasin ou affilié |
items.item_list_id | La liste dans laquelle cet item est apparu (pour le tracking d’impressions) |
items.item_list_name | Nom de la liste |
items.item_variant | Variante du produit (taille, couleur) |
items.location_id | Identifiant de localisation physique |
Comme items est un REPEATED RECORD, accéder aux données au niveau produit nécessite UNNEST :
SELECT event_name, ecommerce.transaction_id, item.item_id, item.item_name, item.item_category, item.price, item.quantity, item.price * item.quantity AS line_revenueFROM `project.analytics_123456789.events_*`, UNNEST(items) AS itemWHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260131' AND event_name = 'purchase'UNNEST sur items développe chaque événement en plusieurs lignes — une par produit. Un achat avec 3 produits devient 3 lignes. Tenez-en compte dans les agrégations : additionner ecommerce.purchase_revenue sur les lignes déimbriquées triplerait le chiffre d’affaires de la transaction. Agrégez toujours le chiffre d’affaires depuis le RECORD ecommerce avant le UNNEST, ou dédupliquez par transaction_id après.
-- Calcul sûr du chiffre d'affaires depuis les items déimbriquésSELECT ecommerce.transaction_id, -- Somme au niveau items (correct pour l'analyse au grain item) SUM(item.price * item.quantity) AS calculated_revenue, -- Depuis le RECORD ecommerce (chiffre d'affaires de transaction de référence) MAX(ecommerce.purchase_revenue) AS transaction_revenueFROM `project.analytics_123456789.events_*`, UNNEST(items) AS itemWHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260131' AND event_name = 'purchase'GROUP BY ecommerce.transaction_iditems.item_params : dimensions personnalisées imbriquées
Ajouté en octobre 2023, item_params est lui-même un REPEATED RECORD dans items. Cela permet des dimensions produit personnalisées — des paires clé-valeur arbitraires attachées à chaque produit, reprenant le fonctionnement d’event_params pour les événements.
Accéder à item_params nécessite UNNEST deux fois : une fois pour items, une fois pour item_params :
SELECT item.item_id, item.item_name, ( SELECT value.string_value FROM UNNEST(item.item_params) WHERE key = 'product_color' ) AS product_color, ( SELECT value.int_value FROM UNNEST(item.item_params) WHERE key = 'warehouse_stock' ) AS warehouse_stockFROM `project.analytics_123456789.events_*`, UNNEST(items) AS itemWHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260131' AND event_name = 'purchase'Les mêmes considérations de détection de type qui s’appliquent à event_params s’appliquent ici — consultez Détection de type event_params GA4 pour le pattern défensif COALESCE en cas de type incertain.
Notez que item_params n’existe que dans les tables postérieures à octobre 2023. L’analyse historique couvrant cette date nécessite une gestion conditionnelle si vos requêtes dépendent des champs item_params.
Couverture des événements pour les champs e-commerce
Tous les événements e-commerce ne renseignent pas tous les champs. La spécification des événements recommandés GA4 définit quels champs sont attendus pour chaque événement :
| Événement | Champs ecommerce | Champs items |
|---|---|---|
view_item_list | Aucun | item_id, item_name, item_list_id, item_list_name |
view_item | Aucun | item_id, item_name, price |
add_to_cart | Aucun | item_id, item_name, price, quantity |
begin_checkout | value | item_id, item_name, price, quantity |
add_payment_info | value, payment_type | item_id, item_name, price, quantity |
purchase | transaction_id, value, shipping_value, tax_value | item_id, item_name, price, quantity, coupon, discount |
refund | transaction_id, value | item_id, quantity |
Filtrez sur le bon nom d’événement avant d’accéder aux champs e-commerce. Interroger ecommerce.transaction_id sur tous les événements retournera principalement des nulls — seuls les événements purchase et refund portent un transaction_id significatif.
Construire une table de produits depuis GA4
Un pattern courant de mart extrait le UNNEST de items en une table dédiée produit-achat :
SELECT event_date, ecommerce.transaction_id, item.item_id, item.item_name, item.item_brand, item.item_category, item.item_category2, item.price, item.quantity, item.price * item.quantity AS line_revenue, item.coupon, item.discountFROM {{ ref('base__ga4__events') }}, UNNEST(items) AS itemWHERE event_name = 'purchase'Associée à un résumé des achats au grain session (une ligne par transaction depuis le RECORD ecommerce), ces deux tables couvrent la plupart des besoins de reporting e-commerce : chiffre d’affaires par produit, performance par catégorie, analyse des coupons, et suivi des remboursements.