Select Star SQL

Les longues traînes

Les longues traînes se rapportent à un petit nombre d’échantillons qui se produisent un grand nombre de fois. Lorsque nous les traçons, ils forment une petite bande à droite du centre de masse qui ressemble à une queue. Ils indiquent la présence de cas exceptionnels dont les comportements inhabituels peuvent nous intéresser. Dans le contexte des exécutions au Texas, la longue traîne fait référence à un petit nombre de comtés qui ont été connus pour effectuer un grand nombre d’exécutions.

Trouvons le pourcentage d’exécutions de chaque comté pour pouvoir choisir ceux qui sont dans la traîne.

Comme on le voit de plus en plus, la forme des tableaux nous en dit beaucoup sur les opérations que nous devons effectuer. (Cela est analogue à l’analyse dimensionnelle en physique.) Dans ce cas, nous pouvons constater que les méthodes que nous avons décrites jusqu’à présent sont inadéquates : le chapitre de Beazley traitait des lignes individuelles de données, mais il est clair que nous devons faire une certaine agrégation pour trouver des données au niveau du comté. Le chapitre Les prétentions d’innocence nous a appris l’agrégation, mais ces fonctions finiraient par regrouper l’ensemble de données dans une seule ligne alors que nous voulons vraiment une ligne par comté.


Le bloc GROUP BY

C’est là que le bloc GROUP BY « litt. grouper par » entre en jeu. Il nous permet de diviser l’ensemble de données et d’appliquer des fonctions agrégées à l’intérieur de chaque groupe, ce qui donne une ligne par groupe. Sa forme la plus basique est GROUP BY <column>, <column>, ... et vient après le bloc WHERE.

Si vous vous souvenez d’Une requête bizarre, la sonnette d’alarme est tirée. Ne venons-nous pas d’apprendre à ne pas mélanger les colonnes agrégées et non agrégées? La différence ici est que les colonnes de regroupement sont les seules colonnes autorisées à être non agrégées. Après tout, toutes les lignes de ce groupe doivent avoir les mêmes valeurs sur ces colonnes afin qu’il n’y ait aucune ambiguïté dans la valeur qui doit être retournée.

Peut-être que vous avez aussi remarqué notre utilisation de AS. C’est ce que nous appelons « aliasing ». Dans le bloc SELECT, <expression> AS <alias> fournit un alias auquel on peut faire référence plus tard dans la requête. Cela nous évite de réécrire des expressions longues, et nous permet de clarifier le but de l’expression.


Le bloc HAVING

L’exercice ci-dessous illustre le filtrage par le bloc WHERE s’est passé avant le regroupement et l’agrégation. Ceci est reflété dans l’ordre de la syntaxe puisque le bloc WHERE précède toujours le bloc GROUP BY.

Tout cela est bien, mais que se passe-t-il si nous voulons filtrer sur le résultat du regroupement et de l’agrégation ? Nous ne pouvons certainement pas sauter dans le futur et y puiser des informations. Pour résoudre ce problème, nous utilisons HAVING (« litt. ayant »).


Pratiquer

Ce quiz est conçu pour remettre en question votre compréhension. Lisez les explications même si vous avez tout compris.


Les requêtes imbriquées

Maintenant, vous pouvez demander, ne serions-nous pas fini si nous pouvions simplement exécuter quelque chose comme ceci?

SELECT
  county,
  PERCENT_COUNT(*)
FROM executions
GROUP BY county

Les pourcentages sont une mesure si commune qu’une telle fonction ne devrait pas exister? Malheureusement non, et peut-être pour une bonne raison : Une telle fonction devrait agréger à la fois dans les groupes (pour obtenir le numérateur) et dans tout l’ensemble de données (pour obtenir le dénominateur). Mais chaque requête a un bloc GROUP BY ou pas. Donc ce dont nous avons vraiment besoin, c’est de deux requêtes séparées, l’une qui s’agrège avec GROUP BY et l’autre qui s’agrège sans GROUP BY. Nous pouvons ensuite les combiner en utilisant une technique appelée « imbrication ».

Voici un exemple de fonctionnement de l’imbrication . Les parenthèses sont importantes pour délimiter la frontière entre la requête interne et la requête externe :

Pour répéter, l’imbrication est nécessaire ici parce que dans la clause WHERE, comme l’ordinateur inspecte une ligne pour décider si sa dernière instruction est de la bonne longueur, il ne peut pas regarder à l’extérieur pour déterminer la longueur maximale sur tout le jeu de données. Nous devons trouver la longueur maximale séparément et l’intégrer dans la clause. Appliquons maintenant le même concept pour trouver le pourcentage d’exécutions de chaque comté.

J’ai ajouté discrètement un bloc ORDER BY. Son format est ORDER BY <column>, <column>, ... et il peut être modifié en ajoutant DESC si vous ne voulez pas l’ordre croissant par défaut.


Le comté de Harris

Est-ce surprenant que Harris (qui abrite la ville de Houston), Dallas, Bexar et Tarrant représentent environ 50% de toutes les exécutions au Texas? Peut-être que oui, surtout si nous partons de l’hypothèse que les exécutions devraient être réparties uniformément entre les comtés. Mais une meilleure première approximation est que les exécutions sont distribuées en fonction de la répartition de la population. Le recensement du Texas de 2010 montre que les 4 comtés avaient une population de 10,0 M soit 40,0% de la population du Texas (25,1 M). Cela rend la constatation un peu moins surprenante.

Mais en réduisant encore la queue, nous réalisons que le comté de Harris représente la majeure partie du delta. Il ne compte que 16,4 % de la population, mais 23,1 % des exécutions, soit près de 50 % de plus qu’il n’est censé le faire.

De nombreuses études ont examiné les raisons pour lesquelles le comté de Harris a été si prolifique et plusieurs facteurs ont été suggérés :


En résumé

Dans cette section, nous avons appris à regrouper des groupes et à utiliser l’imbrication pour utiliser la sortie d’une requête interne dans une requête externe. Ces techniques ont l’avantage très pratique de nous permettre de calculer des pourcentages.

Le MapReduce

Un ajout intéressant est que nous venons d’apprendre à faire MapReduce en SQL. MapReduce est un célèbre paradigme de programmation qui considère les calculs comme se produisant dans une étape de mapper et réduire. Vous pouvez en apprendre plus sur le MapReduce ici.

Le chapitre de Beazley était entièrement consacré au mapping, car il nous montrait comment mapper diverses opérations sur toutes les lignes. Par exemple, SELECT LENGTH(last_statement) FROM executions met la fonction de longueur en correspondance avec toutes les lignes. Ce chapitre nous a montré comment réduire divers groupes de données en utilisant des fonctions d’agrégation; et le chapitre précédent Les prétentions d’innocence était juste un cas spécial dans lequel la table entière est un groupe.

Dans le prochain chapitre, nous découvrirons les JOINs (« joints ») qui nous permettront de travailler avec plusieurs tables.