0Pricing
Coding Interview Prep · Lección

Filtrar por un resultado de ventana

Descubra por qué debe envolver una función de ventana en una subconsulta o CTE para filtrarla

Filtrar por un resultado de ventana es una lección gratuita de Coding Interview Prep en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Coding Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Coding Interview Prep incluye 4 lecciones en total.

Por qué no puede filtrar una ventana en WHERE

Una «trampa» frecuente en las entrevistas: escribir WHERE ROW_NUMBER() OVER (...) = 1 produce un error. Las funciones de ventana no están permitidas en WHERE, GROUP BY ni HAVING.

La razón es el orden lógico de ejecución. WHERE se ejecuta para seleccionar filas antes de que se evalúen las funciones de ventana. La ventana ni siquiera se ha calculado todavía, por lo que no se puede utilizar en un filtro.

La explicación del orden de ejecución

Las funciones de ventana se calculan en una fase específica que se sitúa después de FROM, WHERE, GROUP BY y HAVING, pero antes de el ORDER BY y el LIMIT finales.

Por tanto, cuando se ejecuta WHERE, el rango o el número de fila todavía no existe. Para filtrarlo, debe dejar que la ventana termine primero y, después, filtrar la columna generada en una capa de consulta externa.

El patrón del contenedor de subconsulta

La solución estándar es calcular la función de ventana en una consulta interna (una tabla derivada), asignar un alias al resultado y, después, filtrar ese alias en el WHERE externo.

La tabla derivada debe tener un alias (t en este caso); los entrevistadores se fijan en los candidatos que lo olvidan. Ahora rn es una columna normal que la consulta externa puede comparar.

SELECT *
FROM (
  SELECT
    name, department, salary,
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
  FROM employees
) t
WHERE rn = 1;

El patrón CTE (a menudo más claro)

Una expresión de tabla común hace el mismo trabajo con una estructura más legible. Defina la clasificación en un paso WITH y, después, fíltrela en la consulta principal.

Funcionalmente es idéntica a la subconsulta, pero los entrevistadores suelen preferir las CTE durante la programación en directo porque la intención se entiende de arriba abajo.

WITH ranked AS (
  SELECT
    name, department, salary,
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
  FROM employees
)
SELECT name, department, salary
FROM ranked
WHERE rn = 1;

Ejemplo práctico: los N primeros por grupo

El problema de funciones de ventana más frecuente: «los 3 empleados con los salarios más altos de cada departamento». Clasifique dentro de la CTE y, después, conserve rn <= 3 fuera de ella.

Elija la función de clasificación según el comportamiento de los empates: ROW_NUMBER limita el resultado a exactamente 3 filas por departamento; cambie a RANK/DENSE_RANK si debe incluir los empates en el límite.

WITH ranked AS (
  SELECT department, name, salary,
         ROW_NUMBER() OVER (
           PARTITION BY department ORDER BY salary DESC
         ) AS rn
  FROM employees
)
SELECT department, name, salary
FROM ranked
WHERE rn <= 3
ORDER BY department, rn;

Ejemplo práctico: filtrar un total acumulado

El patrón del contenedor no sirve únicamente para los rangos. Cualquier resultado de ventana —totales acumulados, medias móviles, diferencias de LAG— debe filtrarse de la misma forma.

Aquí calculamos un saldo acumulado y, después, conservamos solo las filas en las que superó 1000 por primera vez. El filtro se encuentra fuera de la capa de ventana.

WITH balances AS (
  SELECT
    account_id, txn_date, amount,
    SUM(amount) OVER (
      PARTITION BY account_id ORDER BY txn_date
    ) AS running_balance
  FROM transactions
)
SELECT *
FROM balances
WHERE running_balance > 1000;

QUALIFY: el atajo de algunas bases de datos

Snowflake, BigQuery, Teradata y DuckDB ofrecen una cláusula QUALIFY que filtra directamente los resultados de ventana, sin necesidad de un contenedor. Se ejecuta después de las funciones de ventana, exactamente donde se necesita.

Mencione QUALIFY para demostrar amplitud de conocimientos, pero indique que no forma parte del estándar SQL y no está disponible en PostgreSQL, MySQL ni SQL Server, donde todavía necesita la subconsulta o la CTE.

-- Snowflake / BigQuery only:
SELECT department, name, salary
FROM employees
QUALIFY ROW_NUMBER() OVER (
  PARTITION BY department ORDER BY salary DESC
) = 1;

No confunda HAVING con el filtrado de ventanas

A veces los candidatos intentan usar HAVING para filtrar un rango. HAVING filtra grupos después de la agregación de GROUP BY y también se ejecuta antes de las funciones de ventana, por lo que tampoco puede hacer referencia a una columna de ventana.

  • WHERE → filtra filas antes de agruparlas y antes de las ventanas.
  • HAVING → filtra grupos agregados, también antes de las ventanas.
  • Filtrar una ventana → requiere una consulta externa (o QUALIFY).

Combinar un prefiltro con un filtro de ventana

A menudo se filtra tanto antes como después de la ventana. Aplique los filtros de filas normales en el WHERE interno, para que la ventana solo vea las filas relevantes, y después filtre el resultado de la ventana en la consulta externa.

En este ejemplo, primero restringimos el resultado a los empleados activos y, después, seleccionamos entre ellos a la persona con el salario más alto de cada departamento. Colocar WHERE active dentro cambia las filas que se clasifican.

WITH ranked AS (
  SELECT department, name, salary,
         ROW_NUMBER() OVER (
           PARTITION BY department ORDER BY salary DESC
         ) AS rn
  FROM employees
  WHERE is_active = true        -- pre-filter before ranking
)
SELECT * FROM ranked
WHERE rn = 1;                   -- post-filter on the window

Nota sobre el rendimiento

Los entrevistadores pueden preguntar si el contenedor perjudica el rendimiento. Por lo general, no: el optimizador trata la subconsulta o la CTE como parte de un único plan y calcula la ventana una sola vez. El hecho de envolverla no provoca un análisis adicional.

Hay una salvedad: en algunos motores, una CTE puede actuar como una barrera de optimización (materializarse), por lo que, en rutas críticas, una tabla derivada o QUALIFY podría generar un mejor plan. Use EXPLAIN para analizarlo si es importante.

Errores comunes

Lista de comprobación final:

  • No coloque nunca una función de ventana en WHERE/HAVING: se producirá un error.
  • Asigne siempre un alias a la tabla derivada; se rechaza una subconsulta sin nombre en FROM.
  • Elija la función de clasificación según el comportamiento de los empates que requiere la pregunta.
  • Use QUALIFY solo donde sea compatible; en los demás casos, recurra al contenedor de CTE o subconsulta.

Comprobación rápida

¿Por qué es necesario un contenedor para filtrar una función de ventana?

Resumen: filtrar resultados de ventana

Ha completado el ciclo de las funciones de ventana de clasificación:

  • Las funciones de ventana se ejecutan después de WHERE/GROUP BY/HAVING, por lo que no puede filtrarlas ahí.
  • Envuelva la ventana en una subconsulta o una CTE (siempre con alias) y filtre el resultado en la consulta externa.
  • Esto permite obtener los N primeros por grupo, la fila más reciente por clave y los umbrales de totales acumulados.
  • QUALIFY es un práctico atajo no estándar disponible únicamente en Snowflake y BigQuery.

Ahora dispone del conjunto completo de herramientas de clasificación que más suelen evaluar los entrevistadores.

Preguntas frecuentes

¿La lección «Filtrar por un resultado de ventana» es gratis?

Sí — el texto completo de «Filtrar por un resultado de ventana» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Coding Interview Prep, actualiza a CoddyKit PRO. El curso de Coding Interview Prep incluye 4 lecciones en total.

¿Qué aprenderé en «Filtrar por un resultado de ventana»?

Descubra por qué debe envolver una función de ventana en una subconsulta o CTE para filtrarla Practicas Coding Interview Prep con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Coding Interview Prep?

No se requiere experiencia previa. Coding Interview Prep en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Filtrar por un resultado de ventana»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Coding Interview Prep?

Sí. Cada lección de Coding Interview Prep incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. OVER, PARTITION BY y ORDER BY
  2. ROW_NUMBER para secuencias únicas
  3. RANK frente a DENSE_RANK con empates
  4. Filtrar por un resultado de ventana
← Volver a Coding Interview Prep