Saltar al contenido principal

Ejemplos de Consultas Athena

Las consultas ad-hoc y de dashboards corren contra la zona curada a través de la tabla Glue analytics.events y el workgroup Athena percus-analytics (que impone un límite de escaneo de 10 GB por consulta — las consultas que exceden el límite son rechazadas, no truncadas silenciosamente).

La tabla analytics.events

El compactor escribe un archivo Parquet snappy por organización-hora al bucket curado, con el layout Hive-style:

s3://percus-analytics-curated/org={id}/year={YYYY}/month={MM}/day={DD}/hour={HH}/part-0000.parquet

Columnas de partición: org, year, month, day, hour. Las particiones se resuelven con partition projection de Athena — no hay crawler ni MSCK REPAIR TABLE que ejecutar.

Cada consulta debe filtrar por org

org usa el tipo de projection injected, así que Athena requiere un filtro de igualdad (WHERE org = '...') en cada consulta. Una consulta sin ese filtro no logra planificarse. Esto es intencional: garantiza que cada consulta queda acotada a una sola organización y nunca escanea el catálogo completo.

Agregar siempre predicados de year/month/day también — podan particiones, de modo que una consulta típica de dashboard (un proyecto, 7 días) escanea bastante menos de 100 MB. El valor de org es el UUID de la organización y coincide con la columna organization_id.

El payload del evento (que varía según event_type) se almacena como string JSON en payload_json; los campos se extraen con json_extract_scalar.

Tasa de completitud por proyecto y rango de fechas

Proporción de sesiones que llegaron a video.completed sobre las sesiones que iniciaron reproducción, para un proyecto en una ventana de 7 días.

SELECT
project_id,
COUNT(DISTINCT CASE WHEN event_type = 'video.completed' THEN session_id END) * 1.0
/ NULLIF(COUNT(DISTINCT CASE WHEN event_type = 'video.played' THEN session_id END), 0)
AS completion_rate
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND project_id = '22222222-2222-2222-2222-222222222222'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26
GROUP BY project_id;

Para un rango que cruza límites de mes o año, componer los predicados de partición (por ejemplo (year = 2026 AND month = 5 AND day >= 28) OR (year = 2026 AND month = 6 AND day <= 4)) o filtrar sobre occurred_at para una ventana exacta de timestamps además de los predicados de partición que hacen el pruning.

Histograma de drop-off (25 / 50 / 75 / 100 %)

Cuántas sesiones distintas alcanzaron cada cuartil. Las marcas 25/50/75 vienen de video.progressed (con payload.percent); el 100 % es video.completed.

SELECT quartile, COUNT(DISTINCT session_id) AS sessions
FROM (
SELECT
session_id,
CAST(json_extract_scalar(payload_json, '$.percent') AS INTEGER) AS quartile
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND project_id = '22222222-2222-2222-2222-222222222222'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26
AND event_type = 'video.progressed'

UNION ALL

SELECT session_id, 100 AS quartile
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND project_id = '22222222-2222-2222-2222-222222222222'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26
AND event_type = 'video.completed'
)
GROUP BY quartile
ORDER BY quartile;

Embudo de CTAs

Clicks de CTA por call-to-action, junto con la base de reproducciones, para leer la conversión.

SELECT
json_extract_scalar(payload_json, '$.cta_id') AS cta_id,
json_extract_scalar(payload_json, '$.cta_name') AS cta_name,
COUNT(*) AS clicks,
COUNT(DISTINCT session_id) AS sessions_with_click
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND project_id = '22222222-2222-2222-2222-222222222222'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26
AND event_type = 'cta.clicked'
GROUP BY 1, 2
ORDER BY clicks DESC;

Para expresarlo como embudo, comparar contra la base de reproducciones en la misma ventana:

SELECT
COUNT(DISTINCT CASE WHEN event_type = 'video.played' THEN session_id END) AS sessions_played,
COUNT(DISTINCT CASE WHEN event_type = 'cta.clicked' THEN session_id END) AS sessions_clicked
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND project_id = '22222222-2222-2222-2222-222222222222'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26;

Top dispositivos y locales

Combinaciones más comunes de dispositivo/OS/browser y locale/país por número de sesiones.

SELECT
device_type, device_os, device_browser, locale, geo_country,
COUNT(DISTINCT session_id) AS sessions
FROM analytics.events
WHERE org = '11111111-1111-1111-1111-111111111111'
AND year = 2026 AND month = 5 AND day BETWEEN 20 AND 26
GROUP BY 1, 2, 3, 4, 5
ORDER BY sessions DESC
LIMIT 50;

Notas de costo y rendimiento

  • Ejecutar todo en el workgroup percus-analytics para que apliquen el límite de escaneo de 10 GB por consulta y la ubicación compartida de resultados. Una alarma de presupuesto de escaneo se dispara cuando una consulta excede ~8 GB (80 % del límite) para que las consultas pesadas se revisen antes de chocar con el límite duro.
  • Seleccionar solo las columnas que necesitas — Parquet es columnar, así que proyecciones angostas escanean dramáticamente menos bytes.
  • Mantener los predicados de org + year/month/day en cada consulta; son los que mantienen una consulta típica de dashboard bajo 100 MB y bajo ~5 segundos.