Análisis de páginas zombi: sin clics ni conversiones

Identifica páginas indexadas que no reciben clics desde Google ni generan conversiones en GA4. Son candidatas a eliminar, redirigir o consolidar para mejorar el crawl budget y la calidad general del sitio.

paginas-zombi-cruce.sql
-- Páginas zombi: sin clics en GSC ni conversiones en GA4
-- Candidatas a eliminar, redirigir o consolidar
WITH gsc_urls AS (
  SELECT
    url,
    SUM(clicks) AS clics_gsc,
    SUM(impressions) AS impresiones_gsc
  FROM
    `your-project.searchconsole.searchdata_url_impression`
  WHERE
    data_date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY) AND CURRENT_DATE()
    AND search_type = 'WEB'
  GROUP BY
    url
),
ga4_urls AS (
  SELECT
    REGEXP_EXTRACT(
      (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'),
      r'(https?://[^?#]+)'
    ) AS url_normalizada,
    COUNT(
      DISTINCT CONCAT(
        user_pseudo_id, '.',
        CAST(
          (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
        AS STRING)
      )
    ) AS sesiones_totales,
    COUNTIF(event_name IN ('generate_lead', 'purchase', 'sign_up')) AS conversiones
  FROM
    `your-project.analytics_XXXXXXXXX.events_*`
  WHERE
    _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY))
      AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
  GROUP BY
    url_normalizada
)
SELECT
  g.url,
  g.impresiones_gsc,
  g.clics_gsc,
  IFNULL(a.sesiones_totales, 0) AS sesiones_ga4,
  IFNULL(a.conversiones, 0) AS conversiones_ga4
FROM
  gsc_urls g
  LEFT JOIN ga4_urls a ON g.url = a.url_normalizada
WHERE
  -- Páginas con impresiones en GSC pero sin clics
  g.clics_gsc = 0
  -- Y sin conversiones en GA4 (o sin datos en GA4)
  AND IFNULL(a.conversiones, 0) = 0
  -- Con un mínimo de impresiones para confirmar que Google las conoce
  AND g.impresiones_gsc >= 10
ORDER BY
  g.impresiones_gsc DESC
LIMIT 100

Explicación paso a paso

  • 3 El CTE gsc_urls agrega datos de GSC usando un periodo de 90 días para capturar incluso páginas con tráfico esporádico.
  • 11 Rango de 90 días (en lugar de 28) para ser más estricto: si en 3 meses no hay clics, la página es realmente zombi.
  • 16 El CTE ga4_urls cuenta sesiones y conversiones de todas las fuentes (no solo orgánico) para ver si la página tiene valor por otros canales.
  • 48 LEFT JOIN para incluir URLs de GSC que ni siquiera aparecen en GA4.
  • 51 Filtra páginas con cero clics en GSC y cero conversiones en GA4.
  • 54 Requiere al menos 10 impresiones para confirmar que Google conoce la URL y la está evaluando.

Ejemplo de resultado esperado

urlimpresiones_gscclics_gscsesiones_ga4conversiones_ga4
https://ejemplo.com/post-2019-obsoleto23450120
https://ejemplo.com/tag/viejo-tema876030
https://ejemplo.com/borrador-publicado456000
https://ejemplo.com/pagina-duplicada-2234050

Variaciones y adaptaciones

Para ser menos estricto, reducir el periodo a 28 días o bajar el mínimo de impresiones. Para excluir páginas que sí reciben tráfico por otros canales, añadir AND IFNULL(a.sesiones_totales, 0) <= 5. Para exportar la lista a una hoja de cálculo y planificar acciones (eliminar, redirigir, actualizar), quitar el LIMIT y exportar todos los resultados.