FIRST_VALUE, LAST_VALUE y límites del marco
Extraiga valores límite y evite el problema habitual del marco de LAST_VALUE
FIRST_VALUE, LAST_VALUE y límites del marco es una lección gratuita de SQL 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 SQL Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Interview Prep incluye 4 lecciones en total.
Obtener valores de los extremos
Los entrevistadores preguntan: «Muestre cada fila junto al primer y el último valor de su grupo». Piense en la fecha del primer inicio de sesión de cada usuario o en el precio más reciente de una partición junto a cada fila de detalle.
Las funciones son FIRST_VALUE y LAST_VALUE. Parecen sencillas, pero LAST_VALUE oculta uno de los problemas más conocidos de los marcos de ventana en SQL. En esta lección aprenderá a utilizar ambas de forma fiable.
Conceptos básicos de FIRST_VALUE
FIRST_VALUE(col) devuelve el valor de col correspondiente a la primera fila de la ventana y lo adjunta a cada fila. Al ordenar por fecha, proporciona a cada fila el valor más antiguo de su partición.
Como el marco predeterminado comienza en la primera fila de la partición, FIRST_VALUE normalmente se comporta exactamente como se espera.
SELECT
user_id,
login_date,
FIRST_VALUE(login_date) OVER (
PARTITION BY user_id
ORDER BY login_date
) AS first_login
FROM logins;El marco de ventana predeterminado
Este es el punto clave. Cuando añade ORDER BY a una ventana, el marco predeterminado es RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
Esto significa que la ventana de cada fila abarca únicamente desde el inicio de la partición hasta la fila actual, no hasta el final. FIRST_VALUE no se ve afectada (la primera fila siempre está dentro del rango), pero LAST_VALUE sí se ve muy afectada.
La trampa de LAST_VALUE
Si ejecuta LAST_VALUE usando únicamente un ORDER BY, la mayoría de los candidatos espera obtener el valor final de la partición. Sin embargo, como el marco termina en la fila actual, el «último valor del marco» no es más que el valor de la propia fila actual.
Por eso, esta consulta devuelve login_date en cada fila, lo que parece un error. Esta es la confusión más frecuente sobre las funciones de ventana.
SELECT
user_id,
login_date,
LAST_VALUE(login_date) OVER (
PARTITION BY user_id
ORDER BY login_date
) AS wrong_last_login
FROM logins;Corregir LAST_VALUE con un marco completo
La solución consiste en ampliar el marco para que abarque toda la partición: ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.
Ahora la ventana de cada fila abarca toda la partición, por lo que LAST_VALUE devuelve el valor final verdadero. Mencione explícitamente esta solución en una entrevista; demuestra que entiende los marcos, no solo los nombres de las funciones.
SELECT
user_id,
login_date,
LAST_VALUE(login_date) OVER (
PARTITION BY user_id
ORDER BY login_date
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING
) AS last_login
FROM logins;Una alternativa más sencilla
Muchos ingenieros evitan el marco por completo: para obtener el último valor, usan FIRST_VALUE con el orden de clasificación invertido.
FIRST_VALUE(login_date) OVER (... ORDER BY login_date DESC) devuelve la fecha más reciente sin necesidad de especificar un marco. Es un recurso sencillo y fácil de recordar que conviene mencionar.
SELECT
user_id,
login_date,
FIRST_VALUE(login_date) OVER (
PARTITION BY user_id
ORDER BY login_date DESC
) AS last_login
FROM logins;ROWS frente a RANGE en los marcos
Hay dos tipos de marcos. ROWS cuenta filas físicas; RANGE agrupa los valores iguales de ORDER BY (filas con el mismo valor).
El marco predeterminado usa RANGE, por lo que los valores repetidos del orden de clasificación comparten el límite del marco. Para corregir LAST_VALUE, prefiera ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING de forma explícita para evitar sorpresas cuando haya valores repetidos.
NTH_VALUE para posiciones arbitrarias
Además del primero y el último, NTH_VALUE(col, n) obtiene el valor que ocupa la posición n dentro del marco, por ejemplo, el segundo precio más alto.
Sigue las mismas reglas de marco que LAST_VALUE, así que combínela con un marco completo cuando quiera obtener el valor n-ésimo de toda la partición en lugar de solo hasta la fila actual.
SELECT
product_id,
price,
NTH_VALUE(price, 2) OVER (
PARTITION BY product_id
ORDER BY price DESC
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING
) AS second_highest_price
FROM prices;Ejemplo resuelto: primero y último juntos
Un informe habitual muestra cada transacción junto al importe de la primera y la última transacción del cliente. Combine ambas funciones y recuerde especificar explícitamente el marco para LAST_VALUE.
Ahora cada fila contiene el primero y el último valor de toda la partición, listos para calcular una diferencia o realizar un paso de etiquetado.
SELECT
customer_id,
txn_date,
amount,
FIRST_VALUE(amount) OVER w AS first_amt,
LAST_VALUE(amount) OVER w AS last_amt
FROM transactions
WINDOW w AS (
PARTITION BY customer_id
ORDER BY txn_date
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING
);Las ventanas con nombre mantienen el código DRY
Observe que la consulta anterior utilizaba una cláusula WINDOW w AS (...) y hacía referencia a OVER w dos veces. Definir la ventana una sola vez evita repetir una especificación de marco extensa e impide que las dos funciones terminen usando definiciones diferentes.
La mayoría de las bases de datos principales admiten ventanas con nombre. Usar una es un detalle elegante que los entrevistadores valoran cuando varias columnas comparten una ventana.
Ejemplo resuelto: diferencia entre el primero y el último
Una pregunta de seguimiento frecuente es cuál fue el cambio entre la primera y la última transacción de un cliente. Con ambos valores extremos en cada fila, réstelos y, si es necesario, elimine los duplicados para dejar una fila por cliente.
Esto combina la solución del marco completo con una operación aritmética sencilla: el tipo de respuesta completa que los entrevistadores esperan ver ensamblada con claridad.
SELECT DISTINCT
customer_id,
LAST_VALUE(amount) OVER w - FIRST_VALUE(amount) OVER w AS first_to_last_delta
FROM transactions
WINDOW w AS (
PARTITION BY customer_id
ORDER BY txn_date
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING
);Comprobación rápida
La confusión clásica de LAST_VALUE.
Resumen
Las funciones de valores de los extremos dependen del marco:
FIRST_VALUEfunciona con el marco predeterminado;LAST_VALUEno.- El marco predeterminado termina en la fila actual, así que corrija
LAST_VALUEconROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, o invierta el orden y useFIRST_VALUE. NTH_VALUE(col, n)obtiene posiciones arbitrarias; las ventanas con nombre mantienen DRY las especificaciones de varias columnas.
Con esto se completa el conjunto de herramientas de LAG, LEAD, NTILE y valores de los extremos.
Preguntas frecuentes
¿La lección «FIRST_VALUE, LAST_VALUE y límites del marco» es gratis?
Sí — el texto completo de «FIRST_VALUE, LAST_VALUE y límites del marco» 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 SQL Interview Prep, actualiza a CoddyKit PRO. El curso de SQL Interview Prep incluye 4 lecciones en total.
¿Qué aprenderé en «FIRST_VALUE, LAST_VALUE y límites del marco»?
Extraiga valores límite y evite el problema habitual del marco de LAST_VALUE Practicas SQL 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 SQL Interview Prep?
No se requiere experiencia previa. SQL 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 «FIRST_VALUE, LAST_VALUE y límites del marco»?
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 SQL Interview Prep?
Sí. Cada lección de SQL 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
- LAG y LEAD para filas adyacentes
- Cambio entre periodos
- NTILE para crear grupos
- FIRST_VALUE, LAST_VALUE y límites del marco