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.
orgorg 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-analyticspara 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/dayen cada consulta; son los que mantienen una consulta típica de dashboard bajo 100 MB y bajo ~5 segundos.