7th Dec 2023 Lectura de 23 minutos ¿Qué son las funciones de ventana SQL? Tihomir Babic SQL funciones de ventana Índice Breve historia de SQL Funciones de ventana ¿Qué es una ventana? Sintaxis de las funciones ventana de SQL Ejemplos de conjuntos de datos y sintaxis Sintaxis Ejemplo #1: OVER () Ejemplo sintáctico nº 2: OVER (ORDER BY) Ejemplo sintáctico nº 3: OVER (PARTITION BY) Ejemplo sintáctico nº 4: OVER (ORDER BY PARTITION BY) ¿Cuáles son las más comunes? Funciones de ventana Ejemplos reales de funciones ventana SQL Ejemplo nº 1: Porcentaje del total Función ventana vs. Función agregada vs. GROUP BY Resuelva este ejercicio para practicar Ejemplo #2: Ordenar Datos Resuelva este ejercicio para practicar Ejemplo #3: Total Resuelve este ejercicio para practicar Ejemplo nº 4: Diferencia entre trimestres Resuelva este ejercicio para practicar SQL Funciones de ventana: Una Ventana a un Mejor Análisis de Datos ¿Necesita mejorar su análisis de datos? Aprenda aquí estas funciones de ventana SQL y llevará sus habilidades de análisis al siguiente nivel. Incluye ejercicios prácticos y explicaciones detalladas. La primera vez que oí hablar de las funciones de ventana de SQL, pensé que se trataba de una extraña unión entre SQL y Windows. Me equivocaba. Las funciones de ventana de SQL no tienen nada que ver con ese famoso sistema operativo. Son funciones SQL que realizan cálculos sobre el conjunto de filas relacionadas con la fila actual. Este conjunto de filas se denomina ventana o marco de ventana, de ahí el nombre de la función. Es posible que también oigas hablar de funciones de ventana en SQL, funciones analíticas o las funciones OVER(). Todos ellos no son más que nombres alternativos para las funciones de ventana de SQL, un conjunto de herramientas extremadamente útiles para el análisis de datos. En este artículo, le mostraremos qué puede hacer con las funciones de ventana y cómo. Empezaré con una breve historia de las funciones ventana de SQL y explicaré por qué se llaman así. A continuación, te guiaré a través de la sintaxis y te mostraré cómo funciona con varios ejemplos. Después de practicar la sintaxis, estaremos listos para ejemplos reales de funciones ventana de la vida de un analista de datos. Y aquí viene lo más jugoso: después de cada ejemplo, hay un ejercicio para que lo resuelvas y aprendas codificando. Sin embargo, la principal fuente de tus conocimientos sobre este tema debe ser nuestro Funciones de ventana curso. Sus 218 ejercicios interactivos cubren en detalle las funciones de la ventana SQL. En otras palabras, aprenderá sobre los marcos de ventana y las cláusulas OVER(), PARTITION BY y ORDER BY. Todo esto es necesario para agregar, clasificar y analizar datos utilizando funciones ventana. Breve historia de SQL Funciones de ventana Las funciones ventana se introdujeron por primera vez en la Base de Datos Oracle8i, que se lanzó en 1998. Sin embargo, se incluyeron en el estándar SQL cinco años después con SQL:2003. Posteriormente, Microsoft las incluyó en SQL Server 2005. Otros sistemas de gestión de bases de datos (DBMS) los siguieron; PostgreSQL los ha soportado desde que PostgreSQL 8.4 fue lanzado en 2009; MariaDB los incluyó con la versión 10.2 (2016), y MySQL los agregó a la versión 8 en 2018. Las funciones de ventana son una característica bastante nueva en SQL. Debido a eso, no forman parte del plan de estudios habitual de SQL. Al aprenderlas, estarás por delante en comparación con muchos usuarios de SQL. ¿Qué es una ventana? Un conjunto de filas relacionadas con la fila actual se denomina ventana o marco de ventana. De ahí el nombre de estas funciones: su resultado se basa en un marco de ventana deslizante. Por ejemplo, puede calcular una suma acumulada como se muestra a continuación: datesalescumulative_sum 2023-10-014,2414,241 2023-10-022,3896,630 2023-10-031,5808,210 2023-10-043,39511,605 2023-10-051,26512,870 La ventana para la suma acumulada 2023-10-04 está resaltada en verde. Incluye la fila actual (para 2023-10-04) y todas las filas anteriores. Por lo tanto, la suma acumulada se calcula como la suma de todas las ventas anteriores y actuales: 4.241 + 2.389 + 1.580 + 3.395 = 11.605. (Observe que la fila resaltada en puntos rojos no está incluida en la ventana ni en la suma). Cuando pasamos a la fila siguiente, la ventana también se desplaza: ahora incluirá todas las filas anteriores (en verde) y la fila actual (en puntos rojos). Ahora la suma acumulada es 4.241 + 2.389 + 1.580 + 3.395 + 1.265 = 12.870. Así pues, la ventana es el conjunto de filas relacionadas con la fila actual que se utilizan en los cálculos para esta fila. La ventana cambia (se desliza) a medida que nos desplazamos por las filas; gracias a estas imágenes de una ventana que se desliza, obtenemos el nombre de estas funciones. Sintaxis de las funciones ventana de SQL La sintaxis de las funciones ventana es: SELECT column_1, column_2, <window_function> OVER(PARTITION BY … ORDER BY … ) AS column_alias FROM table; Esto es lo que hace cada parte <window_function> - Especifica la función a aplicar a esa ventana. OVER() - Define la ventana (conjunto de filas) e indica que se trata de una función ventana; sin esta cláusula, no es una función ventana. <window_frame> - Define el tamaño del marco de la ventana (opcional). PARTITION BY - Divide la ventana en grupos más pequeños llamados particiones (opcional); si se omite, todo el conjunto de resultados es una partición. ORDENAR POR - Ordena las filas dentro del marco de la ventana (opcional), es decir, decide en qué orden se realizará la operación de ventana; si se omite, el orden de las filas dentro de la partición es arbitrario. Las cláusulas adicionales pueden definir aún más la ventana. Su sintaxis es la siguiente [<ROWS or RANGE clause> BETWEEN <lower_bound> AND <upper_bound>] La cláusula ROWS define la ventana en términos del número fijo de filas en relación con la fila actual. La cláusula RANGE hace lo mismo. Pero también tiene en cuenta todas las filas con los mismos valores en las columnas especificadas en la cláusula ORDER BY que la fila actual. Los límites de la ventana pueden definirse como UNBOUNDED PRECEDING - Todas las filas anteriores a la fila actual. n PRECEDING - Un número definido de filas antes de la fila actual. CURRENT ROW - Incluye la fila actual. n FOLLOWING - Un número definido de filas después de la fila actual. UNBOUNDED FOLLOWING - Todas las filas después de la fila actual. Veamos cómo funciona en la práctica. Ejemplos de conjuntos de datos y sintaxis Utilizaremos la tabla album_catalogue en todos estos ejemplos. Puede crearla usted mismo utilizando este script. A continuación se muestra una instantánea de los datos: idalbum_titlealbum_lengthalbum_genreartistcopies_soldsales_period 1Wednesday Morning, 3 A.M0:31:38FolkSimon & Garfunkel10432022_1Q 2EnRoute: John Scofield Trio LIVE1:13:48JazzJohn Scofield Trio5122022_1Q 3Nasty Gal0:39:15FunkBetty Davis8092022_1Q 4The New Folk Sound of Terry Callier0:37:41FolkTerry Callier9032022_1Q 5In a Silent Way0:38:08JazzMiles Davis4282022_1Q El conjunto de datos es una lista de álbumes con su duración, género, artista y datos de ventas, incluyendo el número de copias vendidas y el periodo (trimestres). Los datos llegan hasta el tercer trimestre de 2023. Primero te mostraré varios ejemplos, explicando cada parte crucial de la sintaxis de las funciones de ventana en el camino. Sintaxis Ejemplo #1: OVER () Puede utilizar la función de ventana SUM() sólo con la cláusula OVER() para obtener las ventas totales en el cuarto trimestre de 2022: SELECT sales_period, album_title, artist, copies_sold, SUM (copies_sold) OVER() AS sold_in_4Q_2022 FROM album_catalogue WHERE sales_period = '2022_4Q'; Quiero la suma de las copias vendidas, así que especifico esta columna en SUM(). La cláusula OVER() es obligatoria. Si desea utilizar OVER() sin ninguna de las cláusulas opcionales, simplemente deje los paréntesis vacíos. Utilizo WHERE para obtener sólo los datos del trimestre deseado. Cuando se escribe una consulta como ésta - con un OVER() vacío - todo el conjunto de resultados (columnas seleccionadas, filtros aplicados, etc.) se tiene en cuenta al realizar los cálculos de la función ventana. Aquí, el resultado muestra las ventas individuales de cada álbum vendido en el cuarto trimestre de 2022. También muestra las ventas totales de todos los álbumes vendidos en ese periodo. sales_periodalbum_titleartistcopies_soldsold_in_4q_2022 2022_4QWednesday Morning, 3 A.MSimon & Garfunkel8097,403 2022_4QEnRoute: John Scofield Trio LIVEJohn Scofield Trio6127,403 2022_4QNasty GalBetty Davis3697,403 2022_4QThe New Folk Sound of Terry CallierTerry Callier2147,403 2022_4QIn a Silent WayMiles Davis657,403 2022_4QCold SweatJames Brown2097,403 2022_4QThe Freewheelin' Bob DylanBob Dylan2467,403 2022_4QMy Favorite ThingsJohn Coltrane3777,403 2022_4QA Whole New ThingSly and the Family Stone8167,403 2022_4QFive Leaves LeftNick Drake4007,403 2022_4QHead HuntersHerbie Hancock4097,403 2022_4QIn the Right PlaceDr. John9127,403 2022_4QBlueJoni Mitchell4127,403 2022_4QConciertoJim Hall6127,403 2022_4QDirty MindPrince9417,403 Con la ayuda de SUM() y OVER(), puedo mostrar las ventas individuales de cada álbum y el total trimestral. Ejemplo sintáctico nº 2: OVER (ORDER BY) Puede añadir cláusulas adicionales dentro de la cláusula OVER() para cambiar la definición del marco de la ventana. Una de estas cláusulas es ORDER BY. La cláusula ORDER BY define la ordenación de las filas dentro de un marco de ventana: las filas pueden ser procesadas por la función ventana en un orden determinado. Veamos un ejemplo. Puede calcular la suma acumulada añadiendo ORDER BY a la consulta anterior. En este ejemplo, quiero ver cómo se vende el álbum 'In the Right Place' a lo largo del tiempo y el número acumulado de álbumes vendidos hasta un periodo de tiempo determinado. Esta es la consulta: SELECT sales_period, album_title, artist, copies_sold, SUM (copies_sold) OVER(ORDER BY sales_period ASC) AS cumulative_sum FROM album_catalogue WHERE album_title = 'In the Right Place'; La misma columna copies_sold está en SUM(). Esta vez, OVER() contiene la cláusula ORDER BY. Quiere mostrar las ventas acumuladas desde el primer trimestre hasta el último. Por eso necesita sales_period y ASC en ORDER BY. sales_periodalbum_titleartistcopies_soldcumulative_sum 2022_1QIn the Right PlaceDr. John222222 2022_2QIn the Right PlaceDr. John208430 2022_3QIn the Right PlaceDr. John94524 2022_4QIn the Right PlaceDr. John9121436 2023_1QIn the Right PlaceDr. John9122348 2023_2QIn the Right PlaceDr. John562404 2023_3QIn the Right PlaceDr. John5622966 En cada fila, puede ver las ventas de cada trimestre y la suma acumulada, es decir, la suma del trimestre actual y todos los trimestres anteriores. Por ejemplo, el álbum vendió 94 copias en el tercer trimestre de 2022. El total de ventas en 2022 hasta entonces (o en tres trimestres) es: 222 + 208 + 94 = 524. Ejemplo sintáctico nº 3: OVER (PARTITION BY) Otra cláusula que puede utilizar en OVER() es PARTITION BY. PARTITION BY se utiliza para dividir la ventana en segmentos más pequeños en función de algunos criterios. Por ejemplo, puedes listar los álbumes, sus datos de ventas para el cuarto trimestre de 2022, y las ventas por género para ese trimestre: SELECT album_title, artist, copies_sold, album_genre, SUM (copies_sold) OVER(PARTITION BY album_genre) AS sales_by_genre FROM album_catalogue WHERE sales_period = '2022_4Q'; De nuevo, utilizamos la misma función de ventana SUM(). Esta vez, sin embargo, utilizamos PARTITION BY para dividir la ventana en segmentos más pequeños en función del género del álbum. Todo lo demás permanece igual. La consulta arroja el siguiente resultado. Se trata de un análisis de los datos de ventas de álbumes por género en el último trimestre de 2022. album_titleartistcopies_soldalbum_genresales_by_genre Wednesday Morning, 3 A.MSimon & Garfunkel809Folk2,081 The Freewheelin' Bob DylanBob Dylan246Folk2,081 Five Leaves LeftNick Drake400Folk2,081 The New Folk Sound of Terry CallierTerry Callier214Folk2,081 BlueJoni Mitchell412Folk2,081 Dirty MindPrince941Funk3,247 Nasty GalBetty Davis369Funk3,247 Cold SweatJames Brown209Funk3,247 A Whole New ThingSly and the Family Stone816Funk3,247 In the Right PlaceDr. John912Funk3,247 Head HuntersHerbie Hancock409Jazz2,075 EnRoute: John Scofield Trio LIVEJohn Scofield Trio612Jazz2,075 In a Silent WayMiles Davis65Jazz2,075 ConciertoJim Hall612Jazz2,075 My Favorite ThingsJohn Coltrane377Jazz2,075 Por ejemplo, la suma acumulada para los álbumes de folk es 809 + 246 + 400 + 214 + 412 = 2.081. Ejemplo sintáctico nº 4: OVER (ORDER BY PARTITION BY) También puede utilizar tanto PARTITION BY como ORDER BY en OVER(). Las filas se dividen en segmentos con PARTITION BY y se procesan en un orden determinado por ORDER BY. Con la consulta siguiente, puedo mostrar todos los datos analíticos de los álbumes y calcular la suma acumulada de cada álbum por separado: SELECT sales_period, album_title, artist, copies_sold, SUM (copies_sold) OVER(PARTITION BY album_title ORDER BY sales_period ASC) AS cumulative_sum_by_album FROM album_catalogue; Lo calculo con la ayuda de la función de ventana SUM(), como hice anteriormente. He dividido la ventana por álbum. Esto significa que la suma se acumulará hasta que la función llegue a la última fila de un álbum determinado. Cuando llega a otro álbum, se reinicia y empieza a acumular la suma desde el principio. También utilizo ORDER BY para indicar a la función que acumule la suma desde el trimestre más antiguo hasta el más reciente. sales_periodalbum_titleartistcopies_soldcumulative_sum_by_album 2022_1QA Whole New ThingSly and the Family Stone674674 2022_2QA Whole New ThingSly and the Family Stone257931 2022_3QA Whole New ThingSly and the Family Stone6661,597 2022_4QA Whole New ThingSly and the Family Stone8162,413 2023_1QA Whole New ThingSly and the Family Stone8163,229 2023_2QA Whole New ThingSly and the Family Stone3023,531 2023_3QA Whole New ThingSly and the Family Stone1233,654 2022_1QBlueJoni Mitchell589589 2022_2QBlueJoni Mitchell184773 2022_3QBlueJoni Mitchell2561,029 2022_4QBlueJoni Mitchell4121,441 2023_1QBlueJoni Mitchell4121,853 2023_2QBlueJoni Mitchell991,952 2023_3QBlueJoni Mitchell9952,947 …………… 2022_1QWednesday Morning, 3 A.MSimon & Garfunkel1,0431,043 2022_2QWednesday Morning, 3 A.MSimon & Garfunkel4371,480 2022_3QWednesday Morning, 3 A.MSimon & Garfunkel1841,664 2022_4QWednesday Morning, 3 A.MSimon & Garfunkel8092,473 2023_1QWednesday Morning, 3 A.MSimon & Garfunkel8093,282 2023_2QWednesday Morning, 3 A.MSimon & Garfunkel3253,607 2023_3QWednesday Morning, 3 A.MSimon & Garfunkel6124,219 Puedes ver que la suma acumulada para "A Whole New Thing" es de 3.654. El siguiente álbum ('Blue') comienza con la siguiente fila, por lo que la acumulación se reinicia: la suma acumulada es la misma que las ventas individuales del álbum en el primer trimestre de 2022. A continuación, se acumula hasta llegar al siguiente álbum. El resultado llega hasta el último álbum, que en nuestro caso es 'Wednesday Morning, 3 A.M.'. Con estos ejemplos te he mostrado las formas más comunes de definir marcos de ventana. Pero no son las únicas. También puedes utilizar las cláusulas ROW o RANGE con la sintaxis y los límites que hemos explicado antes. No te preocupes. Verás el uso práctico de esto en ejemplos del mundo real. He utilizado sólo una función, SUM(), a lo largo de estos ejemplos. Esta es una de las muchas funciones de ventana; revisemos rápidamente algunas de las otras. ¿Cuáles son las más comunes? Funciones de ventana Las funciones de ventana más comunes pueden dividirse en tres categorías: Agregado Funciones de ventana: COUNT() - Cuenta el número de filas dentro de una ventana. SUM() - Totaliza valores dados dentro de una ventana. AVG() - Calcula la media de los valores dados dentro de una ventana. MIN() - Encuentra el valor más pequeño dentro de una ventana. MAX() - Encuentra el valor más grande dentro de una ventana. Clasificación Funciones de ventana: ROW_NUMBER() - Clasifica valores secuencialmente, con diferentes rangos para los valores empatados. RANK() - Ordena los valores utilizando el mismo rango para los valores empatados; omite el siguiente rango después de los empates (por ejemplo, 1, 2, 2, 4). DENSE_RANK() - Clasifica los valores utilizando el mismo rango para los valores empatados; no omite el rango siguiente después de los empates (p. ej., 1,2,2,3,4). Analítica Funciones de ventana: LEAD() - Obtiene datos a partir de un desplazamiento definido (es decir, un número determinado de filas) después de la fila actual. LAG() - Obtiene datos de un desplazamiento definido (es decir, un número determinado de filas) antes de la fila actual. Hay más funciones de ventana que pueden resultarle útiles. Consúltalas en nuestra hoja de trucos gratuita de SQL Funciones de ventana. Ejemplos reales de funciones ventana SQL Hasta ahora, me he centrado más en la sintaxis de las funciones ventana de SQL. Ahora te mostraré los usos prácticos más comunes de las funciones ventana y cómo pueden ayudar a los analistas de datos en su trabajo. Estos ejemplos utilizarán el mismo conjunto de datos que antes. Ejemplo nº 1: Porcentaje del total Vamos a mostrar información sobre cada álbum y sus ventas en el primer trimestre de 2023. Además, mostraremos las ventas trimestrales por cada género. A continuación, vamos a calcular cuánto contribuye cada álbum (en porcentaje) a las ventas por género. SELECT album_title, artist, copies_sold, album_genre, SUM(copies_sold) OVER (PARTITION BY album_genre) AS sales_by_genre, (copies_sold*1.0/ SUM(copies_sold) OVER (PARTITION BY album_genre))*100.0 AS percent_of_genre_sales FROM album_catalogue WHERE sales_period = '2023_1Q' ORDER BY album_genre, copies_sold DESC; Para obtener las ventas por género, vuelvo a utilizar la función de ventana SUM(). En la cláusula OVER(), utilizo sólo PARTITION BY. De este modo, puedo dividir la ventana por el género del álbum. En la siguiente línea de código, divido las copias vendidas (de cada álbum) y las divido por las ventas por género. Para ello, basta con copiar el cálculo de la línea anterior. A continuación, multiplique el cociente por 100 para obtener el porcentaje. Verás que también he multiplicado copies_sold por 1,0. Esto es para convertir números enteros a valores decimales. Filtre el trimestre deseado utilizando WHERE. Por último, ordene el resultado alfabéticamente por género y luego descendentemente por copias vendidas. He aquí el resultado: album_titleartistcopies_soldalbum_genresales_by_genrepercent_of_genre_sales Wednesday Morning, 3 A.MSimon & Garfunkel809Folk2,08138.88 BlueJoni Mitchell412Folk2,08119.80 Five Leaves LeftNick Drake400Folk2,08119.22 The Freewheelin' Bob DylanBob Dylan246Folk2,08111.82 The New Folk Sound of Terry CallierTerry Callier214Folk2,08110.28 Dirty MindPrince941Funk3,24728.98 In the Right PlaceDr. John912Funk3,24728.09 A Whole New ThingSly and the Family Stone816Funk3,24725.13 Nasty GalBetty Davis369Funk3,24711.36 Cold SweatJames Brown209Funk3,2476.44 EnRoute: John Scofield Trio LIVEJohn Scofield Trio612Jazz2,07529.49 ConciertoJim Hall612Jazz2,07529.49 Head HuntersHerbie Hancock409Jazz2,07519.71 My Favorite ThingsJohn Coltrane377Jazz2,07518.17 In a Silent WayMiles Davis65Jazz2,0753.13 Comprobemos el cálculo de la primera fila. El álbum de Simon & Garfunkel vendió 809 ejemplares. El total de ventas de álbumes folk de ese trimestre fue de 2.081. Por tanto, el porcentaje de las ventas individuales en las ventas totales del género es de 809/2.081*100 = 38,88%. La suma de los porcentajes de cada género debería ser 100%. Comprobémoslo en un género folclórico: 38,88% + 19,80% + 19,22% + 11,82% + 10,28 % = 100%. Función ventana vs. Función agregada vs. GROUP BY Vuelvo a utilizar la función agregada como función ventana. Podría haber utilizado una simple función agregada SUM() con GROUP BY para obtener las ventas por cada género para el trimestre especificado. ¿Cuál es la diferencia? Una función ventana permite mostrar tanto datos analíticos como agregados (ventas individuales con ventas por género y el cociente de estos valores), mientras que una función agregada utilizada con GROUP BY colapsaría la fila individual y mostraría sólo el valor agregado (la suma de las ventas del trimestre). Resuelva este ejercicio para practicar Utilizando funciones de ventana, reescribe la consulta anterior para que muestre la venta media por género. Además, muestre en qué medida las ventas de cada álbum están por encima o por debajo de la media por género (en porcentaje). Muestra sólo las ventas del tercer trimestre de 2023. Muestra el título del álbum, el artista, las copias vendidas y el género del álbum. Ordena el resultado de forma ascendente por género y ventas de álbumes individuales. Solución: SELECT album_title, artist, copies_sold, album_genre, AVG(copies_sold) OVER (PARTITION BY album_genre) AS average_sales_by_genre, ((copies_sold/AVG(copies_sold) OVER (PARTITION BY album_genre))-1)*100 AS pct_from_average FROM album_catalogue WHERE sales_period = '2023_3Q' ORDER BY album_genre, copies_sold; Salida: album_titleartistcopies_soldalbum_genreaverage_sales_by_genrepct_from_average The New Folk Sound of Terry CallierTerry Callier283Folk561.6-49.61 Five Leaves LeftNick Drake321Folk561.6-42.84 The Freewheelin' Bob DylanBob Dylan597Folk561.66.30 Wednesday Morning, 3 A.MSimon & Garfunkel612Folk561.68.97 BlueJoni Mitchell995Folk561.677.17 A Whole New ThingSly and the Family Stone123Funk533.4-76.94 Dirty MindPrince169Funk533.4-68.32 In the Right PlaceDr. John562Funk533.45.36 Nasty GalBetty Davis808Funk533.451.48 Cold SweatJames Brown1005Funk533.488.41 ConciertoJim Hall263Jazz464-43.32 My Favorite ThingsJohn Coltrane302Jazz464-34.91 EnRoute: John Scofield Trio LIVEJohn Scofield Trio404Jazz464-12.93 Head HuntersHerbie Hancock542Jazz46416.81 In a Silent WayMiles Davis809Jazz46474.35 Ejemplo #2: Ordenar Datos En este ejemplo, voy a utilizar una función de ventana para clasificar los datos. Quiero mostrar cada título de álbum distinto y su longitud y ordenarlos por longitud. El álbum más largo será clasificado primero. SELECT *, RANK() OVER (ORDER BY album_length DESC) AS album_length_rank FROM (SELECT DISTINCT album_title, album_length FROM album_catalogue) AS distinct_album; Empecemos explicando la subconsulta: la utilizamos para seleccionar distintos álbumes y su duración. A continuación, utilizamos la consulta principal para seleccionar todos los datos de la subconsulta. A continuación, utilice la función de ventana RANK() para clasificar los álbumes. También puedes utilizar otras funciones de clasificación, en función de tus datos y tareas. Para que la clasificación funcione como usted desea, utilice la cláusula ORDER BY en OVER(). Especifique la columna por la que desea clasificar y en qué orden. En este caso, es descendentemente por longitud. Aquí tienes la clasificación: album_titlealbum_lengthalbum_length_rank EnRoute: John Scofield Trio LIVE1:13:481 The Freewheelin' Bob Dylan0:44:142 Head Hunters0:41:523 Five Leaves Left0:41:434 My Favorite Things0:40:255 Nasty Gal0:39:156 In a Silent Way0:38:087 Concierto0:38:028 A Whole New Thing0:38:019 The New Folk Sound of Terry Callier0:37:4110 Blue0:36:1511 Cold Sweat0:33:4312 In the Right Place0:33:2213 Wednesday Morning, 3 A.M0:31:3814 Dirty Mind0:30:1415 Resuelva este ejercicio para practicar Ordena cada álbum único por sus ventas dentro de su género. Muestra sólo los datos del primer trimestre de 2023. Muestra el título del álbum, sus ventas, género y rango. Si hay álbumes con el mismo número de ventas, ordénalos por igual y no te saltes el siguiente rango. Solución: SELECT *, DENSE_RANK() OVER (PARTITION BY album_genre ORDER BY copies_sold DESC) AS album_sales_rank FROM (SELECT DISTINCT album_title, copies_sold, album_genre FROM album_catalogue WHERE sales_period = '2023_1Q') AS distinct_album; Salida: album_titlecopies_soldalbum_genrealbum_sales_rank Wednesday Morning, 3 A.M809Folk1 Blue412Folk2 Five Leaves Left400Folk3 The Freewheelin' Bob Dylan246Folk4 The New Folk Sound of Terry Callier214Folk5 Dirty Mind941Funk1 In the Right Place912Funk2 A Whole New Thing816Funk3 Nasty Gal369Funk4 Cold Sweat209Funk5 EnRoute: John Scofield Trio LIVE612Jazz1 Concierto612Jazz1 Head Hunters409Jazz2 My Favorite Things377Jazz3 In a Silent Way65Jazz4 Ejemplo #3: Total En este ejemplo, mostraré el periodo de ventas de un álbum concreto, el título, el artista y las copias vendidas. También añadiré un total acumulado de copias vendidas que incluirá tres filas: la fila actual y las dos anteriores. La suma se calculará desde el trimestre más antiguo hasta el más reciente. SELECT sales_period, album_title, artist, copies_sold, SUM(copies_sold) OVER (ORDER BY sales_period ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS sales_running_total FROM album_catalogue WHERE album_title = 'In a Silent Way'; De nuevo utilizo la función de ventana SUM(). Luego hay un ORDER BY en OVER() para ordenar las ventas y poder sumarlas de forma ascendente. A continuación, tengo que definir el marco de la ventana móvil. El total móvil debe incluir la fila actual y las dos filas anteriores. Estos son los límites inferior y superior especificados en la cláusula ROWS. El límite inferior son las dos filas anteriores, es decir, BETWEEN 2 PRECEDING. El límite superior es CURRENT ROW. Los dos límites se unen en un marco de ventana utilizando la palabra clave AND. Quiero mostrar el cálculo del álbum "In a Silent Way" de Miles Davis, así que filtro los datos utilizando WHERE. Aquí están los totales: sales_periodalbum_titleartistcopies_soldsales_running_total 2022_1QIn a Silent WayMiles Davis428428 2022_2QIn a Silent WayMiles Davis1,0531,481 2022_3QIn a Silent WayMiles Davis191,500 2022_4QIn a Silent WayMiles Davis651,137 2023_1QIn a Silent WayMiles Davis65149 2023_2QIn a Silent WayMiles Davis218348 2023_3QIn a Silent WayMiles Davis8091,092 Comprobemos el resultado y expliquemos qué es un total acumulado. Un total acumulado es similar a un total acumulado (o suma), pero no son lo mismo. El total acumulado le dará la suma de la fila actual y todas las filas anteriores, es decir, el marco de la ventana aumenta con cada fila. Un total acumulado es una suma dentro de un marco de ventana definido que mantiene el mismo tamaño pero se desplaza con cada fila. En nuestro caso, la ventana se define como la fila actual y las dos filas anteriores. Observe los valores resaltados. El total del primer trimestre de 2022 es 428, el mismo que el de la venta individual. No hay filas anteriores, por lo que el total actual sólo incluye la fila actual. El siguiente total acumulado es 428 + 1.053 = 1.481. Suma la línea actual y la anterior, ya que sólo hay una línea anterior. El total actual para el tercer trimestre de 2022 es 428 + 1.053 + 19 = 1.500. Esta es la primera vez que obtiene toda la ventana, es decir, la fila actual y las dos filas anteriores. Al pasar a la fila siguiente, la ventana se moverá pero su tamaño seguirá siendo el mismo. El total para el trimestre siguiente es 428 + 1.053 + 19 + 65 = 1.137. De nuevo, se trata de la fila actual y las dos anteriores. En él intervienen, de nuevo, la fila actual y las dos filas anteriores, pero diferentes en comparación con el trimestre. Resuelve este ejercicio para practicar Reescribe la consulta anterior para que calcule el total acumulado del álbum "The New Folk Sound of Terry Callier". El total acumulado debe calcularse desde el trimestre más antiguo hasta el más reciente. Debe incluir cuatro trimestres: los dos anteriores, el trimestre actual y el siguiente. Indique también el periodo de ventas, el título del álbum, el artista y el número de copias vendidas. Solución: SELECT sales_period, album_title, artist, copies_sold, SUM(copies_sold) OVER (ORDER BY sales_period ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) AS sales_running_total FROM album_catalogue WHERE album_title = 'The New Folk Sound of Terry Callier'; Salida: sales_periodalbum_titleartistcopies_soldsales_running_total 2022_1QThe New Folk Sound of Terry CallierTerry Callier9032,575 2022_2QThe New Folk Sound of Terry CallierTerry Callier4182,789 2022_3QThe New Folk Sound of Terry CallierTerry Callier1,2543,003 2022_4QThe New Folk Sound of Terry CallierTerry Callier2142,641 2023_1QThe New Folk Sound of Terry CallierTerry Callier2142,506 2023_2QThe New Folk Sound of Terry CallierTerry Callier5411,252 2023_3QThe New Folk Sound of Terry CallierTerry Callier2831,038 Ejemplo nº 4: Diferencia entre trimestres En este último ejemplo, mostraré cómo utilizar las funciones de ventana para calcular la diferencia de ventas entre trimestres: SELECT *, LAG(quarterly_copies_sold) OVER (ORDER BY sales_period) AS previous_quarter_sales, quarterly_copies_sold - LAG(quarterly_copies_sold) OVER (ORDER BY sales_period) AS quarterly_sales_difference FROM (SELECT sales_period, SUM(copies_sold) AS quarterly_copies_sold FROM album_catalogue GROUP BY sales_period) AS quarterly_sales; Primero escribo una subconsulta que calcula las ventas totales de cada trimestre. Utilizo la función de agregado SUM() y agrupo los resultados por el periodo de ventas. A continuación, selecciono todos los datos de la subconsulta en la consulta principal. Ahora necesito obtener las ventas del trimestre anterior. Escribiré la función de ventana LAG(), que se utiliza para acceder a los valores de las filas anteriores. El valor al que quiero acceder se especifica en la función. En este caso, son las copias trimestrales vendidas de la subconsulta. Al definir el argumento offset, la función me permite definir hasta dónde quiero retroceder. No lo he definido, así que el desplazamiento por defecto es uno. En otras palabras, la función obtendrá los datos de la fila/trimestre anterior. Pero si quieres ir dos filas/cuartos atrás, entonces escribirías LAG(quarterly_copies_sold, 2). También utilizo ORDER BY en OVER() para asegurarme de que los valores dentro del marco están ordenados del trimestre más antiguo al más reciente. Este uso de la función ventana es para que quede más claro lo que haré en la siguiente línea de código. Aquí es donde se hace el cálculo real de comparar las ventas del trimestre actual y el anterior. Ahora es sencillo: reste la función ventana definida anteriormente de la columna quarterly_copies_sold. Aquí está la salida: sales_periodquarterly_copies_soldprevious_quarter_salesquarterly_sales_difference 2022_1Q9,519NULLNULL 2022_2Q7,5819,519-1,938 2022_3Q4,2737,581-3,308 2022_4Q7,4034,2733,130 2023_1Q7,4037,4030 2023_2Q4,9567,403-2,447 2023_3Q7,7954,9562,839 No hay valores anteriores para 2022_1Q, ya que no hay trimestre anterior. Las ventas trimestrales para 2022_2Q son 7.581. Las ventas del trimestre anterior fueron 9.519. El cálculo muestra que las ventas actuales son 1.938 ejemplares (7.581 - 9.519) inferiores a las ventas del trimestre anterior. Puedes analizar el resto de la producción de la misma manera. Resuelva este ejercicio para practicar Vuelva a escribir la consulta anterior para que muestre la diferencia entre las ventas trimestrales sobre una base interanual; por ejemplo, compare el primer trimestre de 2023 con el primer trimestre de 2022. Muestre el período de ventas, las copias vendidas en el trimestre, las ventas del mismo trimestre del año anterior y la diferencia interanual entre los trimestres. Solución: SELECT *, LAG(quarterly_copies_sold, 4) OVER (ORDER BY sales_period) AS year_over_year_sales, quarterly_copies_sold - LAG(quarterly_copies_sold, 4) OVER (ORDER BY sales_period) AS year_over_year_difference FROM (SELECT sales_period, SUM(copies_sold) AS quarterly_copies_sold FROM album_catalogue GROUP BY sales_period) AS quarterly_sales; Salida: sales_periodquarterly_copies_soldyear_over_year_salesyear_over_year_difference 2022_1Q9,519NULLNULL 2022_2Q7,581NULLNULL 2022_3Q4,273NULLNULL 2022_4Q7,403NULLNULL 2023_1Q7,4039,519-2,116 2023_2Q4,9567,581-2,625 2023_3Q7,7954,2733,522 Si quieres más, aquí tienes ejemplos adicionales de funciones ventana. Para materiales de práctica, echa un vistazo a estos 11 ejercicios de funciones ventana de SQL. SQL Funciones de ventana: Una Ventana a un Mejor Análisis de Datos Este resultó ser un artículo bastante completo sobre las funciones ventana de SQL. Aprendiste las funciones ventana y como funciona cada parte crucial de su sintaxis. También sabes que hay varias categorías de funciones ventana. Las más utilizadas son las funciones ventana de agregación, clasificación y análisis. Los ejemplos prácticos le mostraron cómo se pueden utilizar las funciones ventana en tareas comunes de análisis de datos. Espero que no se haya saltado los ejercicios del artículo. Si lo ha hecho, le recomiendo una vez más que los resuelva. Sólo a través de la práctica podrá entender realmente en qué consisten las funciones ventana de SQL. El recurso más rico para aprender y practicar es nuestro Funciones de ventana curso. Es un curso interactivo que tiene más de 200 ejercicios prácticos y cubre toda la sintaxis de las funciones ventana. Si tienes previstas entrevistas de trabajo, asegúrate de repasar estas preguntas de entrevista sobre funciones de ventana de SQL. Buena suerte, ¡y sigue aprendiendo SQL! Tags: SQL funciones de ventana