Oracle SQL
Le langage SQL (Structured Query Language) est le langage le plus courant en informatique pour gérer les bases de données relationnelles. On l’utilise dans des serveurs web avec MySQL ou MariaDB et aussi dans des applications de bureautique traditionnelles comme Excel ou Access. Oracle SQL est l’implémentation du langage SQL développé par la société Oracle.
L’usage le plus courant d’Oracle SQL est d’interroger et de gérer les données d’une entreprise. Ces applications sont rarement visibles du grand public. Oracle Database sert de base de données derrière certains sites et applications web, sans jamais parler directement au navigateur. L’application web (écrite en Java, PHP, Python, .NET, etc.) envoie les requêtes SQL à Oracle, puis construit la page avec les résultats.
Où s’exercer sur Oracle SQL ?
Pour apprendre le SQL d’Oracle, je conseille d’utiliser le site : https://freesql.com/
Il y a des tables toutes prêtes pour s’exercer mais vous pouvez également y importer vos propres tables si vous créez un compte chez Oracle.
Qu’est-ce qu’une base de données ?
Pour se représenter une base de données, le plus simple est d’imaginer le classeur d’un tableur comme Excel (Microsoft) ou de Calc (LibreOffice).
Base de données
La base de données est similaire à un classeur contenant une ou plusieurs feuilles de calcul. Chaque feuille est une table (c’est de l’anglais mal traduit, on devrait dire tableau).
Table
Chaque feuille du tableur est une table. La table contient des lignes et des colonnes.
Lignes et colonnes
Chaque ligne ou rangée contient des données séparées dans des cellules. Le nom de chaque colonne correspond au nom des champs. Dans un tableau, la première ligne correspond au nom des champs, ce qui n’est pas le cas en SQL où la description de la table est enregistrée séparément.
Type de données des champs
Chaque champ a un type de données : numérique, textuel ou correspondant à une date.
- NUMBER : Nombres entiers ou décimaux.
- FLOAT : Nombres à virgule flottante.
- VARCHAR2 : Chaîne de caractères de longueur variable (jusqu’à 32 768 caractères).
- DATE : Dates et heures (jour, mois, année, heure, minute, seconde)
Concernant le stockage des chiffres à virgule, le décimal privilégie l’exactitude des chiffres, tandis que que le flottant privilégie une représentation compacte et une grande plage de valeurs, au prix d’une certaine approximation.
Trier ou filtrer ?
Avant toute chose, il convient de distinguer le tri ou le filtrage d’une table.
Le tri
Le tri permet de classer les données dans l’ordre croissant ou décroissant. Ce qui signifie :
- pour une donnée textuelle, l’ordre alphabétique ou inverse alphabétique ;
- pour une donnée numérique, de – l’infini vers + l’infini ;
- pour une donnée temporelle, l’ordre chronologique ou inverse chronologique.
Le filtrage
Le filtrage permet de restreindre le nombre d’éléments d’une table. Par exemple, sur le site Allociné, si j’affiche uniquement les salles de cinéma de la Gironde, je fais un filtrage.
Une requête peut cumuler le filtrage et le tri. Par exemple, pour afficher tous les acteurs américains du plus jeune au plus âgés.
Affichage, requête SELECT
Dans les exemples qui vont suivre, nous allons nous exercer avec ces deux tables :
- Table villes (id, code_postal, departement, commune, population) : Les villes de France de plus de 10000 habitants
- Tables acteurs (id, nom, prenom, date_naissance, pays_origine) : Des acteurs célèbres
Pour afficher une seule colonne avec les noms des acteurs, nous utilisons la syntaxe suivante :
SELECT nom_du_champ FROM nom_de_la_table :
SELECT nom
FROM acteurs
Pour afficher plusieurs champs, on les sépare par une virgule :
SELECT nom, prenom
FROM acteurs
Pour afficher tous les champs d’une table, on peut utiliser le raccourci * :
SELECT *
FROM acteurs
Avec l’alias AS, on peut changer le nom de la colonne affichée :
SELECT nom AS "Comédiens"
FROM acteurs
Requête sur les dates
Les dates s’écrivent avec le mot DATE et le format AAAA-MM-JJ. Par exemple, pour afficher les acteurs nés à partir de 1980, on utilise l’opérateur de comparaison > :
SELECT *
FROM acteurs
WHERE DATE_NAISSANCE > DATE '1980-01-01'
Pour afficher les acteurs nés dans les années 80, on peut utiliser l’opérateur BETWEEN :
SELECT * FROM acteurs
WHERE DATE_NAISSANCE BETWEEN DATE '1980-01-01' AND DATE '1989-12-31'
Le type DATE contient toujours une date et une heure. Pour changer le format de la date, la solution la plus courante est TO_CHAR :
SELECT nom, prenom,
TO_CHAR(date_naissance, 'DD/MM/YYYY') AS date_naissance
FROM acteurs;
Résultat : 17/05/1904 pour Jean Gabin, par exemple. Voici d’autres formats :
TO_CHAR(date_naissance, 'YYYY-MM-DD') -- 1904-05-17
TO_CHAR(date_naissance, 'DD Month YYYY') -- 17 Mai 1904
Le nom du mois s’affiche dans la langue de la session Oracle. Pour le forcer en français, ajoutez un troisième argument :
TO_CHAR(date_naissance, 'DD Month YYYY', 'NLS_DATE_LANGUAGE=FRENCH')
Quelques exemples
Table villes (id, code_postal, departement, commune, population)
Afficher toutes les données de la table :
SELECT *
FROM villes
Renvoie les 988 lignes avec toutes les colonnes.
Afficher uniquement le nom des communes et leur population :
SELECT commune, population
FROM villes
Même requête, avec les alias ville et habitants :
SELECT commune AS ville, population AS habitants
FROM villes
Puis un alias avec espaces :
SELECT commune AS ville, population AS "Nombre d'habitants"
FROM villes
Les guillemets doubles sont nécessaires dès que l’alias contient des espaces ou des majuscules à conserver.
Trier les communes de la plus peuplée à la moins peuplée :
SELECT commune, population
FROM villes
ORDER BY population DESC
ASC (croissant) est le sens par défaut. Paris (2 103 778), Marseille et Lyon arrivent en tête.
Afficher les communes du département 33 :
SELECT commune, population
FROM villes
WHERE departement = '33'
Le code est entre apostrophes, car la colonne est du texte. Résultat : 30 communes.
Utiliser les comparaisons > et <>
Communes de plus de 100 000 habitants :
SELECT commune, population
FROM villes
WHERE population > 100000
Communes hors département 75 :
SELECT commune
FROM villes
WHERE departement <> '75'
Paris est la seule commune du département 75. <, >= et <= fonctionnent de la même façon.
Afficher les communes de 50 000 à 100 000 habitants :
SELECT commune, population
FROM villes
WHERE population BETWEEN 50000 AND 100000
BETWEEN inclut les deux bornes. Résultat : 83 communes.
Afficher les communes de Corse (départements 2A et 2B) :
SELECT commune, departement
FROM villes
WHERE departement IN ('2A', '2B')
IN évite d’écrire plusieurs OR. Résultat : Ajaccio, Bastia, Porto-Vecchio et Borgo.
Afficher les communes dont le nom commence par « Saint » :
SELECT commune
FROM villes
WHERE commune LIKE 'Saint%'
% remplace n’importe quelle suite de caractères, _ un seul caractère. Résultat : 79 communes.
Afficher les communes de plus de 100 000 habitants situées dans les Bouches-du-Rhône (13) ou le Rhône (69) :
SELECT commune, population
FROM villes
WHERE departement IN ('13', '69')
AND population > 100000
Résultat : Marseille, Aix-en-Provence, Lyon et Villeurbanne. Avec NOT, WHERE departement NOT IN (’13’, ’69’) renverrait toutes les autres communes. Mets des parenthèses quand tu mélanges AND et OR, car AND est prioritaire.
Table acteurs (id, nom, prenom, date_naissance, pays_origine)
Afficher toutes les données de la table :
SELECT *
FROM acteurs
Renvoie les 100 lignes.
Afficher le nom et le prénom, avec les alias nom_famille et prenom_acteur :
SELECT nom AS nom_famille, prenom AS prenom_acteur
FROM acteurs
Trier les acteurs par pays, puis par nom :
SELECT pays_origine, nom, prenom
FROM acteurs
ORDER BY pays_origine, nom
Trier les acteurs du plus âgé au plus jeune :
SELECT nom, prenom, date_naissance
FROM acteurs
ORDER BY date_naissance
Le second tri place Humphrey Bogart (1899) en premier, suivi de Marlene Dietrich et Jean Gabin. Avec DESC, Adèle Exarchopoulos (1993) arrive en tête.
Afficher les acteurs français :
SELECT nom, prenom
FROM acteurs
WHERE pays_origine = 'France'
Résultat : 40 lignes.
Afficher les acteurs non français
SELECT nom, prenom, pays_origine
FROM acteurs
WHERE pays_origine <> 'France'
L’opérateur <> signifie « différent ».
Afficher les acteurs nés avant 1950 :
SELECT nom, prenom, date_naissance
FROM acteurs
WHERE date_naissance < DATE '1950-01-01'
Afficher les acteurs nés dans les années 1970, triés par date :
SELECT nom, prenom, date_naissance
FROM acteurs
WHERE date_naissance BETWEEN DATE '1970-01-01' AND DATE '1979-12-31'
ORDER BY date_naissance
Résultat : 16 acteurs, de Matt Damon (1970) à Omar Sy (1978).
Afficher les acteurs italiens ou espagnols :
SELECT nom, prenom, pays_origine
FROM acteurs
WHERE pays_origine IN ('Italie', 'Espagne')
Résultat : 7 lignes (4 Italiens et 3 Espagnols).
Afficher les acteurs dont le nom commence par « D » :
SELECT nom, prenom
FROM acteurs
WHERE nom LIKE 'D%'
Résultat : 15 lignes. LIKE est sensible à la casse en Oracle, donc « de Funès » (avec un d minuscule) est exclu. Pour l’inclure :
WHERE UPPER(nom) LIKE 'D%'
On utilise UPPER qui convertit le champ nom en majuscule.
Chercher les acteurs sans date de naissance, puis ceux qui en ont une.
SELECT * FROM acteurs WHERE date_naissance IS NULL; -- 0 ligne
SELECT * FROM acteurs WHERE date_naissance IS NOT NULL; -- 100 lignes
On écrit toujours IS NULL et jamais = NULL. Ici le résultat est vide, car la colonne a été créée avec NOT NULL.
Combiner les conditions avec AND : acteurs français nés à partir de 1980 :
SELECT nom, prenom, date_naissance
FROM acteurs
WHERE pays_origine = 'France'
AND date_naissance >= DATE '1980-01-01';
Résultat : 7 acteurs (Eva Green, Tahar Rahim, Mélanie Laurent, Gaspard Ulliel, Léa Seydoux, Pierre Niney et Adèle Exarchopoulos).
Combiner les conditions avec AND NOT : acteurs français ou américains nés à partir de 1990 :
SELECT nom, prenom, pays_origine
FROM acteurs
WHERE (pays_origine = 'France' OR pays_origine = 'États-Unis')
AND NOT date_naissance < DATE '1990-01-01';
Résultat : Adèle Exarchopoulos et Jennifer Lawrence. Les parenthèses autour du OR sont indispensables, sinon AND s’applique en premier et le résultat change.
Les fonctions d’agrégation SQL
- SUM() : Calcule la somme
- AVG() : Calcule la moyenne
- COUNT() : Compte les lignes ou les valeurs
- MIN() : Recherche la valeur minimale
- MAX() : Recherche la valeur maximale
Par exemple, pour calculer la population moyenne :
SELECT AVG(population) AS "Population moyenne"
FROM villes
ou
SELECT AVG(population) AS Population_moyenne
FROM villes
Sous-requête
Une sous-requête insère une requête à l’intérieur d’une requête. Par exemple, si l’on souhaite extraire les villes qui ont un nom identique mais à des lieux différents en France (recherche de doublons) :
SELECT commune, departement
FROM villes
WHERE (commune) IN (
SELECT commune
FROM villes
GROUP BY commune
HAVING COUNT(*) > 1
)
ORDER BY commune;
Il convient ici de définir le terme HAVING :
- WHERE filtre les lignes individuelles avant que le regroupement ne soit effectué. Il ne peut pas contenir de fonctions d’agrégation.
- HAVING filtre les groupes de résultats après que l’agrégation ait eu lieu. Il peut donc contenir des fonctions d’agrégation.
Calculer la ville qui contient le plus d’habitants :
En sous requête :
SELECT commune
FROM villes
WHERE population = (SELECT MAX(population) FROM villes)
Si vous n’aimez pas les sous-requêtes, on peut limiter à la première rangée dans l’ordre décroissant de population :
SELECT commune, population
FROM communes_10000
ORDER BY population DESC
FETCH FIRST 1 ROW ONLY
Exemples de sous-requêtes
Afficher les communes de Gironde (33) dont la population est supérieure à la moyenne de toutes les communes de la table :
SELECT commune, population
FROM villes
WHERE departement = '33'
AND population > (SELECT AVG(population) FROM villes)
ORDER BY population DESC
La sous-requête entre parenthèses est exécutée en premier. Elle renvoie une seule valeur, ici environ 33 455 habitants, que la requête principale utilise dans la comparaison. Résultat : 5 communes, Bordeaux, Mérignac, Pessac, Talence et Villenave-d’Ornon. Cela marche parce que la sous-requête renvoie un seul résultat. On ne peut pas écrire population > AVG(population) directement, pour la même raison que dans la requête précédente avec MAX().
Afficher les acteurs français plus jeunes que Brad Pitt, du plus âgé au plus jeune :
SELECT nom, prenom, date_naissance
FROM acteurs
WHERE pays_origine = 'France'
AND date_naissance > (SELECT date_naissance
FROM acteurs
WHERE nom = 'Pitt' AND prenom = 'Brad')
ORDER BY date_naissance
La sous-requête récupère la date de naissance de Brad Pitt (18 décembre 1963), puis la requête principale compare avec elle. Résultat : 18 acteurs, de Juliette Binoche (1964) à Adèle Exarchopoulos (1993).
Afficher les acteurs nés en novembre, triés par jour du mois :
SELECT nom, prenom, date_naissance
FROM acteurs
WHERE EXTRACT(MONTH FROM date_naissance) = 11
ORDER BY EXTRACT(DAY FROM date_naissance)
EXTRACT isole une partie de la date : YEAR, MONTH ou DAY. Résultat : 13 acteurs, de Fabrice Luchini à Gaspard Ulliel.