Gestion, analyse et présentations de données

Tags :
  • POK
  • 2024-2025
  • temps 2
Auteurs :
  • Charles Cook

L'objectif de ce POK est d'apprendre comment on nettoie et on gère de la donnée, mais également de montrer comment on présente et traite cette donnée.

Aucun pré-requis

Lors de mes stages, j'ai pu constater que les données constituent un atout majeur pour une entreprise. Les données vont permettre de pouvoir faire une analyse des performances de l'entreprise, mais également de faire des prévisions afin d'ajuster les processus. L'enjeu majeur que constituent les données est également visible lorsque celles-ci sont incomplètes ou erronées, faussant voir paralysant certaines analyses et donc processus. C'est pourquoi j'ai décidé de m'intéresser à la gestion, la manipulation, l'analyse et la présentation de données. Ce sujet est très vaste mais je vais le découper en sous-thématiques :

Tâches

Sprints

Le but final est la compréhension de la gestion des données, depuis la création d'une base de données, jusqu'à l aprésentation de celles-ci, en passant par leur analyse.

Sprint 1

Sprint 2

Horodatage

Date Heures passées Indications
Mardi 12/11 1H Apprentissage SQL
Mercredi 13/11 AM 2H15 Apprentissage SQL
Mercredi 13/11 PM 1H45 Application aux villes de France
Jeudi 14/11 AM 2H Création d'une base de données pour les JO (une tentative a été faite pour la réaliser seul, mais le temps de mise en forme était trop important, je me suis donc rabattu sur une base de données gouvernementale existante pour laquelle la mise en forme était plus rapide)
Jeudi 14/11 PM 1H30 Manipulation de la base de données créée et définition des questions d'analyse
Vendredi 15/11 PM 1H45 Réponses aux questions d'analyse
Samedi 16/11 PM 1H Rédaction Sprint 1
Dimanche 17/11 PM 1H Rédaction Sprint 1

Premier Sprint

Gestion de bases de données et de tables en SQL

Afin d'illustrer les différentes fonctions que nous allons présenter, nous utiliserons deux tables :

Extraire des données d'une table

Afin d'extraire des données d'une base de données relationnelle, on utilise des fonctions SQL :

Fonction Explications
SELECT Renvoie une sous table contenant les éléments selectionnés
DISTINCT Retourne seulement les valeurs uniques
WHERE Permet de réaliser un filtre
ORDER BY Permet de trier les lignes extraites
GROUP BY Permet de grouper les données par catégories
LIKE Utilisé dans un WHERE, pour spécifier ce que l’on cherche
IN Permet de spécifier plusieurs caractères dans un même WHERE
BETWEEN Sélectionne les valeurs comprises dans une plage de valeurs donnée
AS Crée un alias donnant à une table ou une colonne un nom temporaire, tant que la requête est en cours

Quelles sont les villes du Vaucluse (84) ?

Code et Résultats

Code

SELECT * FROM villes_france_free WHERE ville_departement=84;

Ce code permet de créer un table temporaire des villes vauclusiennes dans l'odre alphabétique.

Résultats Villes Vaucluse Triées

Fonction Explications
AND Combine plusieurs conditions pour réaliser une intersection
OR Combine plusieurs conditions pour réaliser une réunion
NOT Permet de réaliser une exclusion
LIMIT Permet de préciser le nombre de lignes que l'on veut extraire
UNION Permet de combiner les résultats de deux ou plusieurs instructions SELECT

Quelles sont les 10 villes les moins peuplées de France en 2012 ?

Code et Résultats

Code

SELECT * FROM villes_france_free
ORDER BY ville_population_2010 ASC
LIMIT 10;

Ce code permet d'extraire les 10 villes les moins peuplées, dans l'ordre croissant du nombre d'habitants.

Résultats TOP 10 villes les moins peuplées

Fonctions d'aggrégation

Une fonction d'aggrégation est une fonction qui réalise des calculs sur un groupe de données et qui renvoie une valeur unique.

Fonction Explications
MAX Renvoie la plus grande valeur d'une colonne
MIN Renvoie la plus petite valeur d'une fonction

Quelles est la population de la ville la plus peuplée du Vaucluse (84) ?

Code et Résultats

Code

SELECT MAX(ville_population_2012)
FROM villes_france_free
WHERE ville_departement=84;

Résultats Cette requête renvoie 90100, correspondant à la population d'Avignon en 2012.

Fonction Explications
COUNT Renvoie le nombre de ligne de la table qui respectent un critère donné
SUM Renvoie la somme d'une colonne spécifiée
AVG Renvoie la moyenne
HAVING Permet de mettre une condition sur les lignes que l’on extrait avec des fonctions d’aggrégation (car WHERE ne le permet pas)

Combien de villes en France possède un nom débutant par 'Saint' ?

Code et Résultats

Code

SELECT COUNT(ville_nom)
FROM villes_france_free
WHERE ville_nom LIKE 'SAINT%';

Résultats Cette requête renvoie 4260, ce qui signifie que 4260 villes commencent par 'Saint' en France.

Quels sont les noms de ville donnés plusieurs fois, du plus au moins rare ?

Code et Résultats

Code

SELECT ville_nom AS 'NOM VILLE', COUNT(ville_nom) AS 'NOMBRE DE VILLE'
FROM villes_france_free
GROUP BY ville_nom
HAVING COUNT(ville_nom)>1
ORDER BY COUNT(ville_nom) DESC;

Résultats Doublons noms de villes

La première colonne donne les noms de ville donnés plusieurs fois et la seconde fait apparaître combien de fois le nom a été donné.

Modifier une table

Il peut être nécessaire de modifier les données d'une table afin de la mettre à jour. Plusieurs fonctions peuvent être utiles :

Ajouter des données
Fonction Explications
INSERT INTO Permet d'ajouter une ligne dans une table

La syntaxe à adopoter est dans ce cas la suivante :

INSERT INTO nom_de_la_table (colonne 1, colonne 2, colonne 3, ...)
VALUES 
(Value 1.1, Value 1.2, Value 1.3, ...),
(Value 2.1, Value 2.2, Value 2.3, ...);

NB: Si on ajoute une valeur pour chaque colonne, il n’est pas nécessaire de préciser le nom de chaque colonne dans les parenthèses après le nom de la table, mais il faut bien respecter l’ordre des données.

Ajouter la ville de New-York à la table villes_france_free.

Code et Résultats

Code Afin d'ajouter une ligne pour la ville de New-York dans la table villes_france_free, le code est le suivant :

INSERT INTO villes_france_free(ville_id,ville_code_commune,ville_nom) VALUES(000, 000, 'NEW YORK');
SELECT * FROM villes_france_free;

Résultats Ajout NY

On remarque qu'une ligne a été ajouté à la fin de la table, pour la ville de New-York.

Supprimer des données
Fonction Explications
DELETE Permet de supprimer un élément, une ligne ou même tous les éléments d'une table

Exemple : Supprimer tous les éléments de la table villes_france_free se ferait avec la requête DELETE FROM villes_france_free;

Fonction Explications
DROP TABLE Permet de supprimer une table (pas seulement son contenu)
Modifier des données
Fonction Explications
UPDATE Mise à jour de la donnée

Mise à jour des données concernant la population de New-York

Code et Résultats

Code

UPDATE villes_france_free 
SET ville_population_2012=8347000, ville_population_2010=819000, ville_population_1999=7428000
WHERE ville_nom='NEW YORK';

Ce code permet de mettre à jour la ligne de la ville de New-York avec les populations en 1999, 2010 et 2012.

Combiner plusieurs tables

En entreprise, tous les employés n’ont pas accès à toutes les données, certaines étant classifiée sensibles. Ainsi, différentes bases de données (ou tables) peuvent être crées avec des niveaux de confidentialité différents. Afin d’extraire des données complètes, il peut être utile d’extraire des données provenant de différentes tables, c’est-ce qu’on appelle des jointures.

Jointures

Il existe différents types de jointure :

Types de jointures Source : w3schools

Dans notre exemple, nous avons dans la table villes_france_free les départements uniquement renseignés par numéro. Nous allons tenter de réaliser une jointure avec la table departement pour renseigner également le nom du département.

Code et Résultats

Code

SELECT t1.ville_departement, t1.ville_nom, t2.departement_nom
FROM villes_france_free.villes_france_free AS t1
JOIN departement.departement AS t2 
ON t1.ville_departement = t2.departement_code
ORDER BY t1.ville_nom;

Résultats Jointure départements Le résultat ci-dessus montre que nous pouvons à présent, grâce à la jointure réalisée entre les deux tables, faire apparaître le nom complet du département auquel appartient la ville et non plus seulement son numéro.

Création d'une base de données, d'une table

Fonctions pour créer une base de données, une table
Fonction Explications
CREATE DATABASE Création d'une base de données
CREATE TABLE Création d'une table dans une base de données
DROP DATABASE Suppression d'une base de données
DROP TABLE Suppression d'une table dans une base de données
ALTER TABLE Permet de modifier une table, en ajoutant une colonne, supprimant une colonne, modifiant le type de donnée d’une colonne, changer le nom du colonne
Contraintes

Il est possible d’ajouter des contrainte sur une colonne lors de la création d’une table. Les contraintes possibles sont les suivantes :

Contrainte Explications
NOT NULL Permet de s’assurer qu’une colonne ne possède pas de valeur NULL
UNIQUE Permet de s’assurer que toutes les valeurs d’une colonne sont différentes
PRIMARY KEY Une combinaison de NOT NULL et UNIQUE
FOREIGN KEY Prévient des actions qui détruirait les liens entre différentes tables
CHECK S’assure que les valeurs d’une colonne respectent bien une condition donnée
DEFAULT Attribue une valeur par défaut pour une colonne si aucune valeur n’est spécifiée

Application : Création et analyse du contenu d'une base de données

Nous allons tenter de créer une base de données afin de pouvoir réaliser une manipulation des données en langage SQL. Pour cela, nous allons nous intéresser aux médailles remportées par pays, durant les jeux Olympiques d'hiver entre 1924 et 2010. Pour cela, nous allons tout d'abord créer un base de données et un table vide.

Création de la base de données et la table

Nous allons créer une base de données intitulée winter_medals, dans laquelle nous allons créer une table medals contenant les informations suivantes :

Code

CREATE DATABASE winter_medals;
CREATE TABLE medals (
    id INT,
    years INT,
    sport VARCHAR(255),
    medal VARCHAR(255),
    country VARCHAR(255),
    pays VARCHAR(255),
    host VARCHAR(255)
);

On voit que pour chaque colonne créée, on précise le type de données qu'elle contient.

Chargement des données

Afin de récolter les données, j'ai utilisé le site Data Gouv permattant d'accéder à un certain nombre de données. J'ai ensuite modifié quelques typographies sur Excel afin de pouvoir charger les données dans la table medals

Code

INSERT INTO medals (id, years, sport, medal, country, pays, host) VALUES
(131666,1924,'biathlon','gold','SUI','Switzerland','FALSE'),
(231666,1924,'biathlon','silver','FIN','Finland','FALSE'),
(331666,1924,'biathlon','bronze','FRA','France','TRUE'),
(431666,1960,'biathlon','gold','SWE','Sweden','FALSE'),
(531666,1960,'biathlon','silver','FIN','Finland','FALSE'),
(631666,1960,'biathlon','bronze','URS','USSR','FALSE'),
(731666,1964,'biathlon','gold','URS','USSR','FALSE'),
(831666,1964,'biathlon','silver','URS','USSR','FALSE'),
(931666,1964,'biathlon','bronze','NOR','Norway','FALSE'),
[…]
(256732514,2010,'snowboard','silver','RUS','Russian Federation','FALSE'),
(256832514,2010,'snowboard','bronze','AUT','Austria','FALSE'),
(256932514,2010,'snowboard','gold','CAN','Canada','TRUE'),
(257032514,2010,'snowboard','silver','FRA','France','FALSE'),
(257132514,2010,'snowboard','bronze','SUI','Switzerland','FALSE');

On obtient ainsi une table contenant 2571 lignes.

On remarque que le la colonne id est en fait une clé primaire, dont les 5 derniers chiffres renvoient au type d’épreuve, et les chiffres avant correspond au numéro de la ligne. Il est donc intéressant de changer le type de la première colonne pour indiquer que c’est une clé primaire :

ALTER TABLE medals ADD PRIMARY KEY (id);
Etude des données

Grâce à la création de cette base de données, nous allons pouvoir répondre de manière plus simple aux questions suivantes, qui nous permettent de débuter une analyse de la donnée :

Question 1 : Quel est le tableau des éditions entre 1924 et 2010, quel pays est le meilleur dans chaque discipline ?

Lors des JO, les pays sont classés selon un tableau des médailles, classant les pays en fonctions du nombre de médailles d'or, puis de médailes d'argent, et enfin de médailles de bronze.

Code

Code

SELECT pays AS 'Pays',
       COUNT(medal) AS 'Total Médailles',
       SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) AS 'GOLD',
       SUM(CASE WHEN medal = 'SILVER' THEN 1 ELSE 0 END) AS 'SILVER',
       SUM(CASE WHEN medal = 'BRONZE' THEN 1 ELSE 0 END) AS 'BRONZE'
FROM medals
GROUP BY pays
ORDER BY GOLD DESC, SILVER DESC, BRONZE DESC;

Explication du code Cette requête crée une table en faisant apparaître 5 colonnes :

  • Une colonne Pays
  • Une colonne comprenant le somme totale de médailles par pays (Total Médailles)
  • Une colonne par couleur de médaille, totalisant le nombre de médailles de chaque couleur par pays (GOLD, SILVER et BRONZE)

Les lignes sont quant à elles classées en fonction du nombre de médailles d'or, puis d'argent, puis de bronze.

Le résultat de la requête est donc le tableau des médailles suivant, réalisé sur l'ensemble des médailles reçues lors des éditions de 1924 à 2010 : Tableau des médailles

Question 2 : Quel pays est en tête du classement des médailles par édition ?

Nous avons réalisé un tableau des médailles sur l'ensemble des éditions entre 1924 et 2010, mais il est intéressant d'extraire le pays en tête du classement lors de chacune des éditions.

Code

Code

SELECT m.years AS 'Année', m.pays AS 'Meilleur Pays', m.nombre_or AS 'Nombre de Titres'
FROM (
    SELECT years, pays,
           SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) AS nombre_or
    FROM medals
    GROUP BY years, pays
) AS m
JOIN (
    SELECT years, MAX(nombre_or) AS max_or
    FROM (
        SELECT years, pays,
               SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) AS nombre_or
        FROM medals
        GROUP BY years, pays
    ) AS subquery
    GROUP BY years
) AS max_counts ON m.years = max_counts.years AND m.nombre_or = max_counts.max_or
ORDER BY m.years;

Explication du code Ce code réalise la jointure de deux sous tables :

  • La première nommée m est un table comprenant 3 colonnes, donnant le nombre de médailles d'or obtenu par chaque pays à chaque édition des JO d'hiver.
  • La seconde, nommée max_counts est une extraction de la première sous-table dans laquelle on conserve seulement la valeur maximum de nombre de médailles d'or par année.

En réalisant une jointure sur les années, on obtient ainsi le résultat ci-dessous.

On obtient ainsi le table suivante, donnant le meilleur pays par année en nombre de titre (médailles d'or) : Meilleur pays par année Remarque : On pourrait être plus précis en prenant en compte égalelement le nombre de médailles d'argent et de bronze

Question 3 : Quel est le classement dans le tableau des médailles de chaque pays par édition ?

Toujours afin d'étudier les performances des pays par édition, nous pouvons essayer d'extraire le classement dans le tableau des médailles par année.

Code

Code

WITH classement AS (
    SELECT pays AS 'Pays',
           years AS 'Année',
           RANK() OVER (
               PARTITION BY years
               ORDER BY 
                   SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) DESC,
                   SUM(CASE WHEN medal = 'SILVER' THEN 1 ELSE 0 END) DESC,
                   SUM(CASE WHEN medal = 'BRONZE' THEN 1 ELSE 0 END) DESC
           ) AS 'Classement'
    FROM medals
    GROUP BY years, pays
)
SELECT Pays, Année, Classement
FROM classement
ORDER BY Pays, Année;

Explication du code Cette requête crée une sous-table classement créant un classement des médailles comme vu précédemment (Question 1), puis extrait le rang de chaque pays par année.

Le résultat obtenu, trié par Pays et par Année, est ci-dessous.

Le résultat obtenu est le suivant : Classement par année

Question 4 : Sur l'ensemble des éditions entre 1924 et 2010, quel pays est le meilleur dans chaque discipline ?

La base de données nous permet également de pouvoir réaliser une étude sur le pays le meilleur (en nombre de titre) en fonction du sport.

Code

Code

SELECT m.sport AS 'Discipline', m.pays AS 'Meilleur Pays', m.nombre_or AS 'Nombre de Titres'
FROM (
    SELECT sport, pays,
           SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) AS nombre_or
    FROM medals
    GROUP BY sport, pays
) AS m
JOIN (
    SELECT sport, MAX(nombre_or) AS max_or
    FROM (
        SELECT sport, pays,
               SUM(CASE WHEN medal = 'GOLD' THEN 1 ELSE 0 END) AS nombre_or
        FROM medals
        GROUP BY sport, pays
    ) AS subquery
    GROUP BY sport
) AS max_counts ON m.sport = max_counts.sport AND m.nombre_or = max_counts.max_or
ORDER BY m.sport;

Explication du code La méthode utilisée pour cette question est la même que pour la question 2, en remplaçant les années par les disciplines.

On obtient ainsi la table suivante : Meilleur par discipline

Question 5 : La performance du pays organisateur (en termes de nombre de médailles) est-elle supérieur que lorsque le même pays n'est pas organisateur ?

Lors de différents évènements sportifs, il existe un match aller, et un match retour. Ceci est organisé car lorsqu'une équipe joue à domicile, ses performances sont souvent meilleures. Il est donc intéressant de regarder si ce phénomène est visible dans les résultats des différents pays aux JO d'hiver.

Code

Code et explication

Table donnant le nombre de médailles obtenu par un pays qlorsqu'il n'est pas organisateur :

SELECT pays AS 'Pays', COUNT(medal) AS 'Nombre_Médailles'
FROM medals
WHERE host = 'FALSE'
GROUP BY pays
ORDER BY pays;

Table donnant le nombre de fois qu'un pays a organisé les jeux d'hiver et le nombre de médailles récoltées lors de ces éditions :

SELECT pays AS 'Pays',
       COUNT(years) AS 'Nombre_Organisateur',
       SUM(nombre_medaille) AS 'Total_Médailles'
FROM (
    SELECT years, pays, COUNT(medal) AS nombre_medaille
    FROM medals
    WHERE host = 'TRUE'
    GROUP BY years, pays
    ORDER BY years
) AS sous_requete
GROUP BY pays
ORDER BY 'Nombre Organisateur' DESC;

Ainsi, avec ces deux tables, nous pouvons obtenir une table donnant pas pays organisateur, le nombre de médailles obtenues à domicile, le nombre de médailles obtenues à l'extérieur, et le nombre de fois que chaque pays a organisé les JO d'hiver :

SELECT not_host.Pays AS Pays, not_host.Nombre_Médailles AS medailles_ext, host.Nombre_Organisateur AS Nbre_orga, host.Total_Médailles AS medailles_dom
FROM(
    SELECT pays AS 'Pays', COUNT(medal) AS 'Nombre_Médailles'
    FROM medals
    WHERE host = 'FALSE'
    GROUP BY pays
    ORDER BY pays) AS not_host
JOIN (
    SELECT pays AS 'Pays',
       COUNT(years) AS 'Nombre_Organisateur',
       SUM(nombre_medaille) AS 'Total_Médailles'
    FROM (
        SELECT years, pays, COUNT(medal) AS nombre_medaille
        FROM medals
        WHERE host = 'TRUE'
        GROUP BY years, pays
        ORDER BY years
    ) AS sous_requete
    GROUP BY pays
    ORDER BY 'Nombre Organisateur' DESC) AS host
ON not_host.Pays=host.Pays;

Finalement, en notant que la base de données recouvre les 21 éditions entre 1924 et 2010, on peut calculer les nombres moyens de médailles reçues à domicile et à l'extérieur par pays :

SELECT Pays,
    ROUND(medailles_dom/Nbre_orga,1) AS Moyenne_médailles_domicile,
    ROUND(medailles_ext/(21-Nbre_orga),1) AS Moyenne_médailles_extérieur
FROM(
    SELECT not_host.Pays AS Pays, not_host.Nombre_Médailles AS medailles_ext, host.Nombre_Organisateur AS Nbre_orga, host.Total_Médailles AS medailles_dom
    FROM(
        SELECT pays AS 'Pays', COUNT(medal) AS 'Nombre_Médailles'
        FROM medals
        WHERE host = 'FALSE'
        GROUP BY pays
        ORDER BY pays) AS not_host
    JOIN (
        SELECT pays AS 'Pays',
        COUNT(years) AS 'Nombre_Organisateur',
        SUM(nombre_medaille) AS 'Total_Médailles'
        FROM (
            SELECT years, pays, COUNT(medal) AS nombre_medaille
            FROM medals
            WHERE host = 'TRUE'
            GROUP BY years, pays
            ORDER BY years
        ) AS sous_requete
        GROUP BY pays
        ORDER BY 'Nombre Organisateur' DESC) AS host
    ON not_host.Pays=host.Pays) AS under_query;

Le résultat obtenu est la table suivante : Moyenne médailles

On remarque à l'aide de cette table que pour la totalité des pays ayant organisé les JO d'hiver (excepté pour la Suisse et l'Allemagne), les performances à domicile sont, au pire, égales à celles à l'extérieur, mais pour la plupart, les performances à domicile sont significativement meilleures (en termes de nombre total de médailles obtenues).

Conclusion Sprint 1

Ce premier sprint nous a permis de comprendre comment créer une base de données relationnelles et comment extraire des tables afin de réaliser les prémices d'une analyse de données en SQL. Cependant, le langage SQL n'est pas le plus adapté pour réaliser l'analyse de données. Nous explorerons plus en profondeur ceci lors du second sprint.

Second Sprint