[ MODELADO DE REVENUE ]

Construcción de un Modelo de Atribución Multi-Touch sobre Eventos Raw de GA4 en BigQuery

Consultas SQL paso a paso con funciones analíticas de ventana para calcular pesos First-Touch, Lead-Creation y Opportunity-Creation (W-Shaped) sobre datos sin muestrear.

4 Septiembre 2026
12 min de lectura
RESUMEN ESTRATÉGICO // ANSWER FIRST

La interfaz gráfica de Google Analytics 4 impone restricciones de muestreo, umbrales de privacidad y ventanas de conversión arbitrarias. Al habilitar la exportación nativa diaria y continua de GA4 a Google BigQuery, obtenemos acceso a cada evento individual sin muestreo. Con SQL podemos diseñar un modelo de atribución que asigne pesos exactos a cada canal en función de su rol en el ciclo comercial B2B.

01.

1. Extracción de Puntos de Contacto desde ga4_events_*

El primer paso consiste en desanidar los parámetros de sesión (`ga_session_id`, `source`, `medium`, `campaign`) y filtrar únicamente los eventos que representen interacción real de tráfico.

01_touchpoints_extraction.sql
-- Extracción y normalización de puntos de contacto de marketing
WITH parsed_events AS (
SELECT
user_pseudo_id,
event_timestamp,
TIMESTAMP_MICROS(event_timestamp) AS event_time,
event_name,
(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS session_id,
COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'source'), traffic_source.source) AS utm_source,
COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'medium'), traffic_source.medium) AS utm_medium,
COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'campaign'), traffic_source.name) AS utm_campaign
FROM `tu_proyecto.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260801' AND '20260831'
),
sessions_summary AS (
SELECT
user_pseudo_id,
session_id,
MIN(event_time) AS session_start,
ARRAY_AGG(utm_source IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_source,
ARRAY_AGG(utm_medium IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_medium,
ARRAY_AGG(utm_campaign IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_campaign,
LOGICAL_OR(event_name = 'generate_lead') AS has_lead_conversion,
LOGICAL_OR(event_name = 'opportunity_created') AS has_deal_conversion
FROM parsed_events
WHERE session_id IS NOT NULL
GROUP BY 1, 2
)
SELECT * FROM sessions_summary;
02.

2. Cálculo de Pesos W-Shaped con Funciones de Ventana

El modelo W-Shaped asigna un 30% del valor de conversión a la primera sesión (First Touch), un 30% a la sesión en que se creó el Lead, un 30% a la sesión en que se creó la Oportunidad en el CRM y reparte el 10% restante equitativamente entre las sesiones intermedias.

02_w_shaped_weights.sql
-- Cálculo de pesos W-Shaped por punto de contacto
WITH user_journey AS (
SELECT
user_pseudo_id,
session_id,
session_start,
CONCAT(COALESCE(session_source, '(direct)'), ' / ', COALESCE(session_medium, '(none)')) AS channel_grouping,
has_lead_conversion,
has_deal_conversion,
ROW_NUMBER() OVER(PARTITION BY user_pseudo_id ORDER BY session_start ASC) AS touch_rank_asc,
ROW_NUMBER() OVER(PARTITION BY user_pseudo_id ORDER BY session_start DESC) AS touch_rank_desc,
COUNT(*) OVER(PARTITION BY user_pseudo_id) AS total_touches
FROM sessions_summary
)
SELECT
user_pseudo_id,
session_id,
channel_grouping,
session_start,
CASE
-- Viaje de 1 solo toque recibe el 100%
WHEN total_touches = 1 THEN 1.0
-- Primer toque (First Touch)
WHEN touch_rank_asc = 1 THEN 0.30
-- Hito de conversión / Oportunidad final
WHEN touch_rank_desc = 1 THEN 0.30
-- Toque de creación de Lead
WHEN has_lead_conversion THEN 0.30
-- Toques intermedios se reparten el 10% restante
ELSE 0.10 / NULLIF(total_touches - 3, 0)
END AS attribution_weight
FROM user_journey;

Optimización de Costes en BigQuery

Particiona siempre las tablas intermedias por session_start (DAY) y clusteriza por user_pseudo_id para reducir el volumen de datos escaneados de gigabytes a solo megabytes.

03.

3. Comparativa de Retorno por Canal: Last-Click vs. W-Shaped

Al ejecutar la consulta sobre un trimestre de datos reales B2B, los resultados revelan discrepancias radicales: canales como LinkedIn Paid y Contenido Orgánico aumentan su contribución en más de un 120%, mientras que Brand Search se reduce a su proporción justa.

Comparativa de Ingresos Atribuidos según Modelo en BigQuery
Canal de MarketingIngresos Last-ClickIngresos W-ShapedDiferencia
LinkedIn Ads (Demanda Temprana)$24,000$68,500+185% (Invisibilizado en last-click)
SEO Técnico & Blog Pilares$38,000$79,200+108% (Crucial en captación inicial)
Google Ads (Brand Search)$142,000$56,300-60% (Sobrevalorado en last-click)
Email Nurturing & Webinars$18,000$35,000+94% (Acelerador de oportunidad)

Controles Técnicos

Muestra telemetría y especificaciones de verificación en producción.