Calcular variación porcentual entre dos periodos
Calcula la variación porcentual de métricas clave entre dos periodos consecutivos. Patrón reutilizable para cualquier reporte comparativo de SEO: semana vs semana, mes vs mes o año vs año.
-- Variación porcentual entre dos periodos
-- Patrón reutilizable: cambiar las fechas y métricas según necesidad
WITH periodo_anterior AS (
SELECT
url,
SUM(clicks) AS clics,
SUM(impressions) AS impresiones
FROM
`your-project.your_dataset.search_data`
WHERE
data_date BETWEEN '2026-03-01' AND '2026-03-31'
GROUP BY
url
),
periodo_actual AS (
SELECT
url,
SUM(clicks) AS clics,
SUM(impressions) AS impresiones
FROM
`your-project.your_dataset.search_data`
WHERE
data_date BETWEEN '2026-04-01' AND '2026-04-30'
GROUP BY
url
)
SELECT
COALESCE(a.url, p.url) AS url,
IFNULL(p.clics, 0) AS clics_anterior,
IFNULL(a.clics, 0) AS clics_actual,
IFNULL(a.clics, 0) - IFNULL(p.clics, 0) AS diferencia_clics,
ROUND(SAFE_DIVIDE(
IFNULL(a.clics, 0) - IFNULL(p.clics, 0),
IFNULL(p.clics, 0)
) * 100, 2) AS variacion_clics_pct,
IFNULL(p.impresiones, 0) AS impresiones_anterior,
IFNULL(a.impresiones, 0) AS impresiones_actual,
ROUND(SAFE_DIVIDE(
IFNULL(a.impresiones, 0) - IFNULL(p.impresiones, 0),
IFNULL(p.impresiones, 0)
) * 100, 2) AS variacion_impresiones_pct
FROM
periodo_actual a
FULL OUTER JOIN periodo_anterior p ON a.url = p.url
ORDER BY
diferencia_clics DESC
LIMIT 50
Explicación paso a paso
- 3 El primer CTE agrega las métricas del periodo anterior (mes pasado en este ejemplo).
- 15 El segundo CTE agrega las mismas métricas del periodo actual.
- 28 COALESCE selecciona la URL de cualquiera de los dos periodos, cubriendo URLs que solo existen en uno.
- 32 SAFE_DIVIDE evita errores de división por cero cuando una URL no tenía datos en el periodo anterior.
- 44 FULL OUTER JOIN incluye URLs que existen solo en uno de los dos periodos, sin perder datos.
- 46 Ordena por diferencia de clics para ver primero las mayores ganancias o pérdidas.
Ejemplo de resultado esperado
| url | clics_anterior | clics_actual | diferencia_clics | variacion_clics_pct | impresiones_anterior | impresiones_actual | variacion_impresiones_pct |
|---|---|---|---|---|---|---|---|
| https://ejemplo.com/nuevo-post | 0 | 456 | 456 | null | 0 | 6789 | null |
| https://ejemplo.com/guia-seo | 234 | 345 | 111 | 47.44 | 4567 | 5678 | 24.32 |
| https://ejemplo.com/pagina-antigua | 187 | 45 | -142 | -75.94 | 3456 | 987 | -71.44 |
Variaciones y adaptaciones
Para comparar semanas en lugar de meses, ajustar las fechas en los CTEs a rangos de 7 días. Para hacer la comparación dinámica (siempre el mes actual vs anterior), usar DATE_TRUNC(CURRENT_DATE(), MONTH) y DATE_SUB. Para añadir más métricas (posición, CTR), incluirlas en ambos CTEs con la misma lógica.