7th Dec 2023 24 minutes de lecture Que sont les fonctions SQL Window ? Tihomir Babic sql fonctions de fenêtrage Table des matières Brève histoire de SQL Fonctions de fenêtrage Qu'est-ce qu'une fenêtre ? Syntaxe des fonctions de fenêtre SQL Exemples de données et de syntaxe Exemple de syntaxe n° 1 : OVER () Exemple de syntaxe n° 2 : OVER (ORDER BY) Exemple de syntaxe n° 3 : OVER (PARTITION BY) Exemple de syntaxe n° 4 : OVER (ORDER BY PARTITION BY) Quelles sont les fonctions les plus courantes de Fonctions de fenêtrage? Exemples réels de fonctions de fenêtre SQL Exemple n° 1 : Pourcentage du total Fonction de fenêtre vs. fonction d'agrégation vs. GROUP BY Résoudre cet exercice pour s'entraîner Exemple n° 2 : classement des données Résoudre cet exercice pour s'entraîner Exemple n° 3 : Total courant Résolvez cet exercice pour vous entraîner Exemple n° 4 : Différence d'un trimestre à l'autre Résoudre cet exercice pour s'entraîner SQL Fonctions de fenêtrage: une fenêtre pour une meilleure analyse des données Vous avez besoin d'améliorer votre analyse de données ? Apprenez ces fonctions SQL window ici et vous ferez passer vos compétences d'analyse au niveau supérieur. Exercices pratiques et explications détaillées inclus ! Lorsque j'ai entendu parler pour la première fois des fonctions SQL window, j'ai pensé qu'il s'agissait d'un mariage étrange entre SQL et Windows. Je me trompais. Les fonctions SQL window n'ont rien à voir avec le célèbre système d'exploitation. Il s'agit de fonctions SQL qui effectuent des calculs sur l'ensemble des lignes liées à la ligne courante. Cet ensemble de lignes est appelé fenêtre ou cadre de fenêtre, d'où le nom de la fonction. Vous pouvez également entendre parler de fonctions de fenêtrage en SQL, de fonctions analytiques ou de fonctions OVER(). Il ne s'agit là que de noms alternatifs pour les fonctions de fenêtrage SQL, un ensemble d'outils extrêmement utiles pour l'analyse des données. Dans cet article, nous allons vous montrer ce que vous pouvez faire avec les fonctions de fenêtrage et comment. Je commencerai par un bref historique des fonctions SQL window et j'expliquerai pourquoi elles sont appelées ainsi. Ensuite, je vous guiderai à travers la syntaxe et vous montrerai comment elle fonctionne à l'aide de plusieurs exemples. Après avoir pratiqué la syntaxe, nous serons prêts pour des exemples concrets de fonctions window dans la vie d'un analyste de données. Et voici la partie la plus intéressante : après chaque exemple, il y a un exercice à résoudre et à apprendre par le codage. Cependant, la source principale de vos connaissances sur ce sujet devrait être notre Fonctions de fenêtrage cours. Ses 218 exercices interactifs couvrent en détail les fonctions de la fenêtre SQL. En d'autres termes, vous apprendrez à connaître les cadres de fenêtres et les clauses OVER(), PARTITION BY, et ORDER BY. Tout cela est nécessaire pour agréger, classer et analyser les données à l'aide des fonctions de fenêtre. Brève histoire de SQL Fonctions de fenêtrage Les fonctions de fenêtre ont été introduites pour la première fois dans la base de données Oracle8i, publiée en 1998. Cependant, elles ont été incluses dans la norme SQL cinq ans plus tard avec SQL:2003. Microsoft les a ensuite incluses dans SQL Server 2005. D'autres systèmes de gestion de bases de données (SGBD) ont suivi ; PostgreSQL les prend en charge depuis la sortie de PostgreSQL 8.4 en 2009 ; MariaDB les a incluses dans la version 10.2 (2016), et MySQL les a ajoutées à la version 8 en 2018. Les fonctions de fenêtre sont une fonctionnalité relativement nouvelle de SQL. C'est pourquoi elles ne font pas partie du programme d'études habituel de SQL. En les apprenant, vous aurez une longueur d'avance par rapport à de nombreux utilisateurs de SQL. Qu'est-ce qu'une fenêtre ? Un ensemble de lignes liées à la ligne courante est appelé une fenêtre ou un cadre de fenêtre. D'où le nom de ces fonctions : leur résultat est basé sur un cadre de fenêtre coulissante. Par exemple, vous pouvez calculer une somme cumulative comme indiqué ci-dessous : 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 fenêtre pour la somme cumulée 2023-10-04 est surlignée en vert. Elle comprend la ligne actuelle (pour 2023-10-04) et toutes les lignes précédentes. La somme cumulée est donc calculée comme la somme de toutes les ventes précédentes et actuelles : 4.241 + 2.389 + 1.580 + 3.395 = 11.605 (la ligne délimitée par des points rouges n'est pas incluse dans la fenêtre ni dans la somme). Lorsque nous passons à la ligne suivante, la fenêtre se déplace également : elle inclut désormais toutes les lignes précédentes (en vert) et la ligne actuelle (en pointillés rouges). La somme cumulée est maintenant de 4 241 + 2 389 + 1 580 + 3 395 + 1 265 = 12 870. La fenêtre est donc l'ensemble des lignes liées à la ligne actuelle qui sont utilisées dans les calculs pour cette ligne. La fenêtre change (glisse) au fur et à mesure que l'on passe d'une ligne à l'autre ; c'est grâce à ces images d'une fenêtre qui glisse que l'on obtient le nom de ces fonctions. Syntaxe des fonctions de fenêtre SQL La syntaxe des fonctions de fenêtre est la suivante : SELECT column_1, column_2, <window_function> OVER(PARTITION BY … ORDER BY … ) AS column_alias FROM table; Voici ce que fait chaque partie : <window_function> - Spécifie la fonction à appliquer à cette fenêtre. OVER() - Définit la fenêtre (ensemble de lignes) et indique qu'il s'agit d'une fonction de fenêtre ; sans cette clause, il ne s'agit pas d'une fonction de fenêtre. <window_frame> - Définit la taille du cadre de la fenêtre (facultatif). PARTITION BY - Divise la fenêtre en groupes plus petits appelés partitions (facultatif) ; en cas d'omission, l'ensemble des résultats constitue une seule partition. ORDER BY - Trie les lignes dans le cadre de la fenêtre (facultatif), c'est-à-dire qu'il décide de l'ordre dans lequel l'opération de fenêtrage sera effectuée ; s'il est omis, l'ordre des lignes à l'intérieur de la partition est arbitraire. Des clauses supplémentaires peuvent définir plus précisément la fenêtre. Leur syntaxe est la suivante : [<ROWS or RANGE clause> BETWEEN <lower_bound> AND <upper_bound>] La clause ROWS définit la fenêtre en termes de nombre fixe de lignes par rapport à la ligne actuelle. La clause RANGE fait de même. Mais elle prend également en compte toutes les lignes dont les valeurs dans les colonnes spécifiées dans la clause ORDER BY sont identiques à celles de la ligne actuelle. Les limites de la fenêtre peuvent être définies comme suit UNBOUNDED PRECEDING - Toutes les lignes précédant la ligne actuelle. n PRECEDING - Un nombre défini de lignes avant la ligne actuelle. CURRENT ROW - Inclut la ligne actuelle. n FOLLOWING - Un nombre défini de lignes après la ligne actuelle. UNBOUNDED FOLLOWING - Toutes les lignes après la ligne actuelle. Voyons maintenant comment cela fonctionne en pratique. Exemples de données et de syntaxe Nous utiliserons le tableau album_catalogue dans tous ces exemples. Vous pouvez le créer vous-même à l'aide de ce script. Un aperçu des données est présenté ci-dessous : 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 L'ensemble de données est une liste d'albums avec leur durée, leur genre, leur artiste et les données relatives aux ventes, y compris le nombre d'exemplaires vendus et la période (trimestres). Les données vont jusqu'au troisième trimestre 2023. Je vais d'abord vous montrer plusieurs exemples, en expliquant au passage chaque partie cruciale de la syntaxe des fonctions de fenêtrage. Exemple de syntaxe n° 1 : OVER () Vous pouvez utiliser la fonction de fenêtrage SUM() avec la seule clause OVER() pour obtenir le total des ventes au quatrième trimestre 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'; Je veux la somme des exemplaires vendus, je spécifie donc cette colonne dans SUM(). La clause OVER() est obligatoire. Si vous souhaitez utiliser OVER() sans aucune des clauses facultatives, laissez simplement les parenthèses vides. J'utilise WHERE pour ne sortir que les données du trimestre souhaité. Lorsque vous écrivez une requête comme celle-ci - avec un OVER() vide - l'ensemble des résultats (colonnes sélectionnées, filtres appliqués, etc.) est pris en compte lors de l'exécution des calculs de la fonction de fenêtre. Ici, le résultat indique les ventes individuelles de chaque album vendu au cours du quatrième trimestre 2022. Il indique également les ventes totales de tous les albums vendus au cours de cette période. 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 Avec l'aide de SUM() et OVER(), je suis en mesure d'afficher les ventes de chaque album et le total trimestriel. Exemple de syntaxe n° 2 : OVER (ORDER BY) Vous pouvez ajouter des clauses supplémentaires à l'intérieur de la clause OVER() pour modifier la définition du cadre de la fenêtre. L'une de ces clauses est ORDER BY. La clause ORDER BY définit le tri des lignes à l'intérieur d'un cadre de fenêtre : les lignes peuvent être traitées par la fonction de fenêtre dans un ordre donné. Voyons un exemple. Vous pouvez calculer la somme cumulée en ajoutant ORDER BY à la requête précédente. Dans cet exemple, je souhaite connaître les ventes de l'album "In the Right Place" au fil du temps et le nombre cumulé d'albums vendus jusqu'à une période donnée. Voici la requête : 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 même colonne copies_sold se trouve dans SUM(). Cette fois, OVER() contient la clause ORDER BY. Vous souhaitez afficher les ventes cumulées du premier au dernier trimestre. C'est pourquoi vous avez besoin de sales_period et ASC dans 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 Dans chaque ligne, vous pouvez voir les ventes pour chaque trimestre et la somme cumulée, c'est-à-dire la somme du trimestre en cours et de tous les trimestres précédents. Par exemple, l'album s'est vendu à 94 exemplaires au troisième trimestre 2022. Le total des ventes en 2022 jusqu'à cette date (ou en trois trimestres) est le suivant : 222 + 208 + 94 = 524. Exemple de syntaxe n° 3 : OVER (PARTITION BY) Une autre clause que vous pouvez utiliser dans OVER() est PARTITION BY. PARTITION BY est utilisée pour diviser la fenêtre en segments plus petits sur la base de certains critères. Par exemple, vous pouvez dresser la liste des albums, de leurs ventes pour le quatrième trimestre 2022 et des ventes par genre pour ce 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'; Nous utilisons à nouveau la même fonction de fenêtre SUM(). Cette fois-ci, nous utilisons PARTITION BY pour diviser la fenêtre en segments plus petits basés sur le genre de l'album. Tout le reste est identique. La requête renvoie le résultat ci-dessous. Il s'agit d'une analyse des données relatives aux ventes d'albums par genre pour le dernier trimestre 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 Par exemple, la somme cumulée pour les albums folk est de 809 + 246 + 400 + 214 + 412 = 2 081. Exemple de syntaxe n° 4 : OVER (ORDER BY PARTITION BY) Vous pouvez également utiliser PARTITION BY et ORDER BY dans OVER(). Les lignes sont divisées en segments avec PARTITION BY et traitées dans un ordre donné par ORDER BY. En utilisant la requête ci-dessous, je peux afficher toutes les données analytiques des albums et calculer la somme cumulée pour chaque album séparément : 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; Je calcule cette somme à l'aide de la fonction de fenêtre SUM(), comme je l'ai fait précédemment. J'ai partitionné la fenêtre par album. Cela signifie que la somme sera cumulée jusqu'à ce que la fonction atteigne la dernière ligne d'un album particulier. Lorsqu'elle atteint un autre album, elle se réinitialise et recommence à accumuler la somme depuis le début. J'utilise également ORDER BY pour demander à la fonction de cumuler la somme du premier au dernier trimestre. 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 Vous pouvez voir que la somme cumulée pour "A Whole New Thing" est de 3 654. L'album suivant ("Blue") commence à la ligne suivante, de sorte que le cumul est réinitialisé : la somme cumulée est la même que les ventes individuelles de l'album au cours du premier trimestre 2022. Ensuite, elle s'accumule jusqu'à l'album suivant. Le résultat va jusqu'au dernier album, qui est "Wednesday Morning, 3 A.M." dans notre cas. Je vous ai montré les façons les plus courantes de définir des cadres de fenêtres avec ces exemples. Mais ce ne sont pas les seules. Vous pouvez également utiliser les clauses ROW ou RANGE avec la syntaxe et les limites que nous avons expliquées précédemment. Ne vous inquiétez pas. Vous verrez l'utilisation pratique de ces clauses dans des exemples concrets. Je n'ai utilisé qu'une seule fonction, SUM(), tout au long de ces exemples. Il s'agit d'une des nombreuses fonctions de fenêtre ; passons rapidement en revue quelques-unes des autres. Quelles sont les fonctions les plus courantes de Fonctions de fenêtrage? Les fonctions de fenêtre les plus courantes peuvent être classées en trois catégories : Agrégat Fonctions de fenêtrage: COUNT() - Compte le nombre de lignes dans une fenêtre. SUM() - Totalise des valeurs données dans une fenêtre. AVG() - Calcule la moyenne de valeurs données dans une fenêtre. MIN() - Trouve la plus petite valeur dans une fenêtre. MAX() - Trouve la plus grande valeur dans une fenêtre. Classement Fonctions de fenêtrage: ROW_NUMBER() - Classe les valeurs séquentiellement, avec des rangs différents pour les valeurs ex æquo. RANK() - Classe les valeurs en utilisant le même rang pour les valeurs ex æquo ; saute le rang suivant après les ex æquo (par exemple, 1, 2, 2, 4). DENSE_RANK() - Classe les valeurs en utilisant le même rang pour les valeurs liées ; ne saute pas le rang suivant après les égalités (par exemple, 1,2,2,3,4). Analytique Fonctions de fenêtrage: LEAD() - Obtient des données à partir d'un décalage défini (c.-à-d. un nombre donné de lignes) après la ligne actuelle. LAG() - Permet d'obtenir des données à partir d'un décalage défini (c'est-à-dire un nombre donné de lignes) avant la ligne actuelle. Il existe d'autres fonctions de fenêtre qui pourraient vous être utiles. Consultez-les dans notre feuille de contrôle gratuite SQL Fonctions de fenêtrage. Exemples réels de fonctions de fenêtre SQL Jusqu'à présent, je me suis concentré sur la syntaxe des fonctions SQL window. Je vais maintenant vous montrer les utilisations pratiques les plus courantes des fonctions de fenêtre et comment elles peuvent aider les analystes de données dans leur travail. Ces exemples utilisent le même ensemble de données que précédemment. Exemple n° 1 : Pourcentage du total Montrons des informations sur chaque album et ses ventes au cours du premier trimestre 2023. En outre, nous montrerons les ventes trimestrielles par genre. Calculons ensuite la part de chaque album (en pourcentage) dans les ventes par genre. 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; Pour obtenir les ventes par genre, j'utilise à nouveau la fonction de fenêtre SUM(). Dans la clause OVER(), je n'utilise que PARTITION BY. De cette façon, je peux diviser la fenêtre en fonction du genre de l'album. Dans la ligne de code suivante, je divise les exemplaires vendus (de chaque album) et je les divise par les ventes par genre. Pour ce faire, il suffit de copier le calcul de la ligne précédente. Ensuite, il faut multiplier le quotient par 100 pour obtenir le pourcentage. Vous remarquerez que j'ai également multiplié copies_sold par 1,0. Cela permet de convertir les nombres entiers en valeurs décimales. Filtrez le trimestre souhaité à l'aide de WHERE. Enfin, classez les résultats par ordre alphabétique de genre, puis par ordre décroissant d'exemplaires vendus. Voici le résultat : 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 Vérifions le calcul pour la première ligne. L'album de Simon & Garfunkel s'est vendu à 809 exemplaires. Le total des ventes d'albums folk pour ce trimestre est de 2 081. Le pourcentage des ventes individuelles par rapport aux ventes totales du genre est donc de 809/2 081*100 = 38,88 %. La somme des pourcentages pour chaque genre devrait être de 100 %. Vérifions-le pour un genre folklorique : 38,88 % + 19,80 % + 19,22 % + 11,82 % + 10,28 % = 100 %. Fonction de fenêtre vs. fonction d'agrégation vs. GROUP BY J'utilise à nouveau la fonction d'agrégation comme fonction de fenêtre. J'aurais pu utiliser une simple fonction agrégée SUM() avec GROUP BY pour obtenir les ventes par genre pour le trimestre spécifié. Quelle est alors la différence ? Une fonction de fenêtre vous permet d'afficher à la fois des données analytiques et des données agrégées (les ventes individuelles avec les ventes par genre et le quotient de ces valeurs), tandis qu'une fonction agrégée utilisée avec GROUP BY réduirait la ligne individuelle et n'afficherait que la valeur agrégée (la somme des ventes pour le trimestre). Résoudre cet exercice pour s'entraîner À l'aide des fonctions de fenêtre, réécrivez la requête ci-dessus de manière à afficher les ventes moyennes par genre. Indiquez également dans quelle mesure les ventes de chaque album sont supérieures ou inférieures à la moyenne par genre (en pourcentage). N'affichez que les ventes du troisième trimestre 2023. Afficher le titre de l'album, l'artiste, le nombre d'exemplaires vendus et le genre de l'album. Trier les résultats par ordre croissant en fonction du genre et des ventes de chaque album. Solution : 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; Résultat : 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 Exemple n° 2 : classement des données Dans cet exemple, j'utiliserai une fonction de fenêtre pour classer des données. Je souhaite afficher chaque titre d'album distinct et sa durée, puis les classer par ordre de longueur. L'album le plus long sera classé en premier. 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; Commençons par expliquer la sous-requête : nous l'utilisons pour sélectionner des albums distincts et leur longueur. Ensuite, nous utilisons la requête principale pour sélectionner toutes les données de la sous-requête. Utilisez maintenant la fonction de fenêtre RANK() pour classer les albums. Vous pouvez également utiliser d'autres fonctions de classement, en fonction de vos données et de vos tâches. Pour que le classement fonctionne comme vous le souhaitez, utilisez la clause ORDER BY dans OVER(). Spécifiez la colonne par laquelle vous voulez classer et dans quel ordre. Dans ce cas, il s'agit d'un classement décroissant par longueur. Voici le classement : 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 Résoudre cet exercice pour s'entraîner Classez chaque album unique en fonction de ses ventes dans son genre. Ne montrez que les données du premier trimestre 2023. Indiquez le titre de l'album, ses ventes, son genre et son rang. Si certains albums ont le même nombre de ventes, classez-les de la même manière et ne sautez pas le rang suivant. Solution : 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; Sortie : 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 Exemple n° 3 : Total courant Dans cet exemple, j'indiquerai la période de vente d'un album particulier, son titre, son artiste et le nombre d'exemplaires vendus. J'ajouterai également un total courant des exemplaires vendus qui comprendra trois lignes : la ligne actuelle et les deux lignes précédentes. La somme doit être calculée du premier au dernier trimestre. 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'; J'utilise à nouveau la fonction de fenêtre SUM(). Ensuite, il y a un ORDER BY dans OVER() pour ordonner les ventes afin que nous puissions les additionner de manière ascendante. Ensuite, je dois définir le cadre de la fenêtre mobile. Le total courant doit inclure la ligne actuelle et les deux lignes précédentes. Il s'agit des limites inférieure et supérieure spécifiées dans la clause ROWS. La limite inférieure correspond aux deux lignes précédentes, c'est-à-dire BETWEEN 2 PRECEDING. La limite supérieure est CURRENT ROW. Les deux bornes sont assemblées dans un cadre de fenêtre à l'aide du mot-clé AND. Je veux afficher le calcul pour l'album "In a Silent Way" de Miles Davis, je filtre donc les données à l'aide du mot-clé WHERE. Voici les totaux en cours : 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 Vérifions le résultat et expliquons ce qu'est un total courant. Un total courant est similaire à un total cumulatif (ou somme), mais ce n'est pas la même chose. Le total cumulé vous donne la somme de la ligne actuelle et de toutes les lignes précédentes, c'est-à-dire que le cadre de la fenêtre augmente avec chaque ligne. Un total courant est une somme à l'intérieur d'une fenêtre définie qui reste de la même taille mais qui se déplace avec chaque ligne. Dans notre cas, la fenêtre est définie comme étant la ligne actuelle et les deux lignes précédentes. Examinez les valeurs en surbrillance. Le total courant pour le premier trimestre 2022 est de 428, soit le même que pour la vente individuelle. Comme il n'y a pas de lignes précédentes, le total courant ne comprend que la ligne actuelle. Le total courant suivant est 428 + 1053 = 1481. Il additionne la ligne actuelle et la ligne précédente, puisqu'il n'y a qu'une seule ligne précédente. Le total courant pour le troisième trimestre 2022 est 428 + 1053 + 19 = 1500. C'est la première fois que vous obtenez la fenêtre entière, c'est-à-dire la ligne actuelle et les deux lignes précédentes. Lorsque vous passez à la ligne suivante, la fenêtre se déplace mais sa taille reste la même. Le total courant pour le trimestre suivant est de 1053 + 19 + 65 = 1137. Il implique à nouveau la ligne actuelle et les deux lignes précédentes - mais des lignes différentes par rapport au trimestre. Résolvez cet exercice pour vous entraîner Réécrivez la requête ci-dessus pour qu'elle calcule le total courant de l'album "The New Folk Sound of Terry Callier". Le total cumulé doit être calculé du premier au dernier trimestre. Il doit inclure quatre trimestres : les deux précédents, le trimestre en cours et le suivant. Indiquez également la période de vente, le titre de l'album, l'artiste et le nombre d'exemplaires vendus. Solution : 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'; Sortie : 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 Exemple n° 4 : Différence d'un trimestre à l'autre Dans ce dernier exemple, je vais montrer comment utiliser les fonctions de la fenêtre pour calculer la différence de ventes entre les 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; J'écris d'abord une sous-requête qui calcule les ventes totales pour chaque trimestre. J'utilise la fonction d'agrégation SUM() et je regroupe les résultats par période de vente. Ensuite, je sélectionne toutes les données de la sous-requête dans la requête principale. Je dois maintenant obtenir les ventes du trimestre précédent. Je vais écrire la fonction de fenêtre LAG(), qui est utilisée pour accéder aux valeurs des lignes précédentes. La valeur à laquelle je souhaite accéder est spécifiée dans la fonction. Dans ce cas, il s'agit des exemplaires trimestriels vendus à partir de la sous-requête. En définissant l'argument offset, la fonction me permet de définir jusqu'où je veux remonter. Comme je ne l'ai pas défini, le décalage par défaut est de un. En d'autres termes, la fonction récupère les données de la ligne/du trimestre précédent(e). Mais si vous souhaitez remonter de deux lignes/trimestres, vous devez écrire LAG(quarterly_copies_sold, 2). J'utilise également ORDER BY dans OVER() pour m'assurer que les valeurs du cadre sont triées du trimestre le plus ancien au plus récent. Cette utilisation de la fonction window permet de clarifier ce que je vais faire dans la ligne de code suivante. C'est ici que s'effectue le calcul proprement dit de la comparaison des ventes du trimestre en cours et du trimestre précédent. C'est simple maintenant : soustrayez la fonction window définie ci-dessus de la colonne quarterly_copies_sold. Voici le résultat : 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 Il n'y a pas de valeurs précédentes pour 2022_1Q, car il n'y a pas de trimestre précédent. Les ventes trimestrielles pour 2022_2Q sont de 7 581. Les ventes du trimestre précédent étaient de 9 519. Le calcul montre que les ventes actuelles sont inférieures de 1 938 exemplaires (7 581 - 9 519) aux ventes du trimestre précédent. Vous pouvez analyser le reste des résultats de la même manière. Résoudre cet exercice pour s'entraîner Réécrivez la requête ci-dessus pour qu'elle indique la différence entre les ventes trimestrielles d'une année sur l'autre - par exemple, comparez le premier trimestre 2023 avec le premier trimestre 2022. Indiquez la période de vente, les exemplaires vendus au cours du trimestre, les ventes pour le même trimestre de l'année précédente et la différence d'une année sur l'autre entre les trimestres. Solution : 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; Sortie : 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 vous en voulez plus, voici d'autres exemples de fonctions de fenêtre. Pour vous entraîner, consultez ces 11 exercices sur les fonctions de fenêtre SQL. SQL Fonctions de fenêtrage: une fenêtre pour une meilleure analyse des données Cet article s'est avéré très complet sur les fonctions de fenêtre SQL. Vous avez appris à connaître les fonctions de fenêtre et le fonctionnement de chaque partie cruciale de leur syntaxe. Vous savez également qu'il existe plusieurs catégories de fonctions de fenêtre. Les plus couramment utilisées sont les fonctions fenêtre agrégées, de classement et analytiques. Les exemples pratiques vous ont montré comment les fonctions fenêtre peuvent être utilisées dans des tâches courantes d'analyse de données. J'espère que vous n'avez pas sauté les exercices de l'article. Si c'est le cas, je vous recommande à nouveau de les résoudre. Ce n'est qu'en pratiquant que vous pourrez vraiment comprendre ce que sont les fonctions SQL window. La ressource la plus riche pour l'apprentissage et la pratique est notre cours de Fonctions de fenêtrage est la ressource la plus riche pour apprendre et s'entraîner. Il s'agit d'un cours interactif qui comporte plus de 200 exercices pratiques et couvre la syntaxe complète des fonctions de fenêtre. Si vous avez des entretiens d'embauche en vue, n'oubliez pas de répondre à ces questions d'entretien sur les fonctions de fenêtre SQL. Bonne chance et continuez à apprendre le langage SQL ! Tags: sql fonctions de fenêtrage