SQL - Introduction
1 Structured Query Language
Le SQL est un langage standardisé utilisé pour interagir avec des bases de données relationnelles.
Il permet de créer, manipuler, interroger et gérer les données stockées dans des tables.
Norme SQL
SQL est un language normé dont la dernière version est SQL:2023.
Les SGBD ne respectent pas exactement la norme SQL.
À un niveau avancé d’utilisation, il y a des différences entre les SGBD.
- Sinon c’est très ressemblant.
- DuckDB’s SQL dialect closely follows the conventions of the PostgreSQL dialect. few exceptions
Composantes du langage
- Définition de Données
- Manipulation de Données
- Contrôle des Transactions
- Contrôle d’accès aux Données
- Manipulation de Données - CRUD
- Définition de Données - Créer/Modifier/Supprimer une table
- Contrôle des Transactions - BEGIN, COMMIT, ROLLBACK
- Contrôle d’accès aux Données - GRANT REVOKE
2 Définition de Données
Ici nous n’allons travailler que sur une seule table à la fois
Créer une table
CREATE TABLE joueuse (
INT,
id_joueuse
nom TEXT,
prenom TEXT,DATE,
date_naissance INT,
elo BOOLEAN,
est_arbitre
code_pays TEXT,FLOAT
taux_victoires );
C’est comme créer les colonnes d’un tableau.
Tout en spécifiant les types.
CREATE avancé
CREATE TABLE echecs.joueuse (
PRIMARY KEY,
id_joueuse SERIAL VARCHAR(50) NOT NULL,
nom VARCHAR(50) NOT NULL,
prenom TIMESTAMP,
date_naissance INT CHECK (elo > 0),
elo VARCHAR(100) UNIQUE,
mail BOOLEAN DEFAULT false,
est_arbitre VARCHAR(2),
code_pays FLOAT CHECK (taux_victoires BETWEEN 0 AND 1)
taux_victoires );
NOT NULL
: l’attribut doit être renseignéUNIQUE
: chaque valeur de l’attribut est unique (pas de doublons)CHECK
: pour vérifier la cohérence d’un attribut
- Schéma echecs : j’y viens juste après
- SERIAL : séquence numérique, on en reparle dans quelques minutes
- VARCHAR(50) pour limiter la taille des valeurs
- DEFAULT : valeur par défaut (principalement lors de l’INSERT)
Important : La PK est NOT NULL et UNIQUE
Schéma
Utile lorsque le nombre de tables devient grand.
- Organisation des objets, clarté
- Gestion des permissions
CREATE SCHEMA echecs;
- Pamplemousse -> Millésime
- Vente de légume
- Utiliser la même bdd pour la gestion RH, le métier et la compta
- créer un schéma pour séparer les tables
Table dans un schéma
CREATE TABLE echecs.club (
PRIMARY KEY,
id_club SERIAL VARCHAR(100) NOT NULL,
nom VARCHAR(100) NOT NULL,
ville DATE
date_creation );
Déplacer la table joueuse dans le schéma echecs :
ALTER TABLE joueuse SET SCHEMA echecs;
Par défaut les objets sont créés dans le schéma public
.
Ça devient rapidement un joyeux bazar si on ne range pas ses tables.
C’est comme créer un fichier dans un dossier.
Bonnes pratiques
- Nom de table représentatif et au singulier
- Pas de majuscules, pas d’accents
- Mots séparés par des underscores (snake_case)
- Ne pas utiliser de mots clés réservés (date, user…)
- Ne pas avoir de colonne qui porte le même nom que sa table
dans les requêtes : mots clés en majuscules
Modifier une colonne
Modifier le type :
ALTER TABLE joueuse
ALTER COLUMN nom TYPE VARCHAR(80);
Renommer :
ALTER TABLE echecs.joueuse
RENAME COLUMN date_naissance TO dnais;
Créer/Supprimer une colonne
Ajout :
ALTER TABLE echecs.joueuse
ADD COLUMN id_club INT;
Suppression :
ALTER TABLE echecs.joueuse
DROP COLUMN taux_victoires;
Définir une clé étrangère
- Nous venons de créer une colonne
id_club
- Lions maintenant cette colonne à la table club
ALTER TABLE echecs.joueuse
ADD CONSTRAINT fk_id_club
FOREIGN KEY (id_club)
REFERENCES echecs.club(id_club);
Dans la table joueuse, l’attribut id_club
a pour valeur soit :
- une valeur de
id_club
de la table club - NULL
Autres possibilités
- Renommer une table
- Ajouter / Supprimer une contrainte
- Définir / Supprimer une valeur par défaut
Supprimer une table
DROP TABLE echecs.joueuse;
Cette opération est irréversible !
Elle supprime définitivement :
- la table
- toutes les données qu’elle contient
DROP TABLE IF EXISTS echecs.joueuse; -- utile pour les scripts SQL
3 Insérer des données
-- Rappel du CREATE
CREATE TABLE echecs.club (
PRIMARY KEY,
id_club SERIAL VARCHAR(100) NOT NULL,
nom VARCHAR(100) NOT NULL,
ville DATE
date_creation );
INSERT INTO echecs.club
(nom, ville, date_creation)VALUES
'C''Chartres Echecs', 'Chartres', '1991-09-01'),
('Bischwiller', 'Bischwiller', '1976-09-01'),
('Asnieres - le Grand Echiquier', 'Asnieres', '1987-03-20'),
('Tours des Hauts-De-France', 'Saint-Quentin', '1999-12-01'); (
Pourquoi l’on n’insère pas la colonne id_club ? 😕
Attention à bien mettre les virgules au bon endroit
- Pas de double quotes en SQL !!!
- ’’ : Pour ajouter un simple quote dans une chaine
Séquence
La colonne id_club est une séquence gérée par le SGBD.
Les valeurs sont générées automatiquement à l’insertion et la séquence est incrémentée (1, 2, 3…).
Il est possible de créer et gérer ses propres séquences :
CREATE SEQUENCE nom_sequence START 1 INCREMENT BY 1;
SELECT currval('nom_sequence'); -- dernière valeur utilisée
SELECT nextval('nom_sequence'); -- prochaine valeur
ALTER SEQUENCE nom_sequence RESTART WITH nouvelle_valeur;
DROP SEQUENCE nom_sequence;
4 Lire des données
SELECT * FROM <schema>.<table>
pour tout afficher.
SELECT *
FROM echecs.club;
id_club | nom | ville | date_creation |
---|---|---|---|
1 | C’Chartres Echecs | Chartres | 1991-09-01 |
2 | Bischwiller | Bischwiller | 1976-09-01 |
3 | Asnieres - le Grand Echiquier | Asnieres | 1987-03-20 |
4 | Tours des Hauts-De-France | Saint-Quentin | 1999-12-01 |
*
: toutes les colonnes
Colonnes à afficher
Listez les colonnes à afficher après le SELECT
SELECT nom,
prenom,
eloFROM echecs.joueuse;
nom | prenom | elo |
---|---|---|
Guichard | Pauline | 2357 |
Daulyte-Cornette | Deimante | 2371 |
Navrotescu | Andreea | 2338 |
Sebag | Marie | 2448 |
Millet | Sophie | 2366 |
Skrichempko | Almira | 2361 |
Filtrer les lignes
Filtrez sur les lignes avec une clause WHERE
.
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE elo > 2400;
nom | prenom | elo |
---|---|---|
Sebag | Marie | 2448 |
Plusieurs filtres
Le mot clé AND
permet d’ajouter d’autres filtres.
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE elo < 2400
AND prenom LIKE 'A%';
nom | prenom | elo |
---|---|---|
Navrotescu | Andreea | 2338 |
Skrichempko | Almira | 2361 |
1 seul WHERE
plusieurs AND
LIKE ‘A%’ : commence par A, j’y viens dans 2 min
Vous pouvez autoriser plusieurs conditions avec OR
.
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE elo > 2400
OR prenom LIKE 'A%';
nom | prenom | elo |
---|---|---|
Sebag | Marie | 2448 |
Navrotescu | Andreea | 2338 |
Skrichempko | Almira | 2361 |
Opérations booléennes
- Utilisation des mots-clés
AND
,OR
etNOT
- AND prioritaire sur le OR
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE elo > 2400 OR (prenom LIKE 'A%' AND nom NOT LIKE 'N%') ;
LIKE
SELECT *
FROM echecs.joueuse
WHERE prenom LIKE 'A%' -- commence par A
OR prenom LIKE '%A' -- termine par A
OR prenom LIKE '%A%' -- contient au moins un A
OR UPPER(prenom) LIKE '%A%' -- contient au moins un A ou un a
OR prenom LIKE 'A__' -- commence par A suivi de 2 autres caractères
%
: représente entre 0 et une infinité de caractères_
: représente exactement 1 caractère
MAJUSCULES ≠ minuscules
ILIKE insensible à la casse
'abc' SIMILAR TO 'abc' true
'abc' SIMILAR TO 'a' false
'abc' SIMILAR TO '%(b|d)%' true
'abc' SIMILAR TO '(b|c)%' false
'-abc-' SIMILAR TO '%\mabc\M%' true
'xabcy' SIMILAR TO '%\mabc\M%' false
Plage de valeurs
BETWEEN
permet de spécifier une plage de valeurs numériques.
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE elo BETWEEN 2350 AND 2400;
nom | prenom | elo |
---|---|---|
Guichard | Pauline | 2357 |
Daulyte-Cornette | Deimante | 2371 |
Millet | Sophie | 2366 |
Skrichempko | Almira | 2361 |
Valeurs dans une liste
Vous pouvez spécifier qu’un attribut doit appartenir à un liste avec IN
.
Ou inversement avec NOT IN
.
SELECT nom,
prenom,
eloFROM echecs.joueuse
WHERE prenom IN ('Deimante', 'Sophie');
nom | prenom | elo |
---|---|---|
Daulyte-Cornette | Deimante | 2371 |
Millet | Sophie | 2366 |
Possible de lister des valeurs numériques
Filtre sur les attributs booléens
SELECT *
FROM echecs.joueuse
WHERE est_arbitre IS TRUE;
SELECT *
FROM echecs.joueuse
WHERE [NOT] est_arbitre;
Ordonner le résultat
ORDER BY
pour ordonner selon plusieurs colonnes.
SELECT nom,
prenom,
eloFROM echecs.joueuse
ORDER BY elo,
DESC; taux_victoires
nom | prenom | elo |
---|---|---|
Navrotescu | Andreea | 2338 |
Guichard | Pauline | 2357 |
Skrichempko | Almira | 2361 |
Millet | Sophie | 2366 |
Daulyte-Cornette | Deimante | 2371 |
Sebag | Marie | 2448 |
- ORDER BY 2 : 2e colonne
- Remarque : pas obligé de SELECT les colonnes du OBY
Afficher n lignes
SELECT nom,
prenom,
eloFROM echecs.joueuse
LIMIT 3;
nom | prenom | elo |
---|---|---|
Guichard | Pauline | 2357 |
Daulyte-Cornette | Deimante | 2371 |
Navrotescu | Andreea | 2338 |
5 Mise à jour de données
UPDATE echecs.joueuse
SET elo = 2399,
= 'Popo'
prenom WHERE id_joueuse = 1;
SELECT id_joueuse,
nom,
prenom,
eloFROM echecs.joueuse
WHERE id_joueuse = 1;
id_joueuse | nom | prenom | elo |
---|---|---|---|
1 | Guichard | Popo | 2399 |
Màj globale
Imaginons que vous souhaitez modifier le elo
de toutes les joueuses.
UPDATE echecs.joueuse
SET elo = elo + 100;
Généralement un message d’avertissement vous demande si vous êtes certain de vouloir mettre à jour toutes les lignes.
6 Suppression de données
Supprimer une joueuse :
DELETE FROM echecs.joueuse
WHERE id_joueuse = 1;
Vider la table :
DELETE FROM echecs.joueuse;
7 Validation des opérations
Et si ? Vous avez exécuté par erreur :
DELETE FROM echecs.joueuse;
😱
Il y a un système de transactions avec les mots clés :
- BEGIN
- COMMIT
- ROLLBACK
Attention : il n’y a pas de garde-fou lorsque vous êtes en Auto-commit.
Vu plus tard dans le cours
8 Dates et Heures
Type DATE
Quelques opérations avec le type DATE
.
SELECT nom,
prenom,EXTRACT(YEAR FROM date_naissance) AS annee_naissance,
+ INTERVAL '10 years' AS anniv_dix_ans,
date_naissance CURRENT_DATE, date_naissance) AS age
AGE(FROM echecs.joueuse
WHERE date_naissance >= '1991-04-20'
OR date_naissance BETWEEN '1991-04-20' AND '1992-12-31'
OR EXTRACT(MONTH FROM date_naissance) = 4;
Type TIMESTAMP
Pour stocker la date et l’heure
CREATE TABLE echecs.club (
PRIMARY KEY,
id_club SERIAL VARCHAR(100) NOT NULL,
nom VARCHAR(100) NOT NULL,
ville TIMESTAMP
date_creation );
Utilisations
INSERT INTO echecs.club (nom, ville, date_creation)
VALUES ('C''Chartres Echecs', 'Chartres', '1991-09-01 20:00:00');
INSERT INTO echecs.club (nom, ville, date_creation)
VALUES ('Bischwiller', 'Bischwiller', CURRENT_TIMESTAMP);
Vous pouvez utiliser également sur le type TIMESTAMP :
EXTRACT
,BETWEEN
,- les opérateurs de comparaison
9 Valeurs nulles
Tester si un attribut est NULL
Joueuses dont le mail n’est pas renseigné :
SELECT *
FROM echecs.joueuse
WHERE mail IS NULL;
Et inversemenent :
SELECT *
FROM echecs.joueuse
WHERE mail IS NOT NULL;
COALESCE
En PostgreSQL, la fonction COALESCE :
- prend un nombre quelconque de paramètres
- retourne le 1er paramètre dont la valeur est NON NULLE
c(x1, x2, ... xn):if x1:
return x1
else:
return c(x2, ... xn)
NVL pour Oracle (à ne pas confondre avec MVL)
COALESCE - Exemple
SELECT COALESCE(mail, tel, 'pas de contact')
FROM echecs.joueuse
WHERE id_joueuse = 1
La requête ci-dessus va afficher :
- Si mail est NON NULL ➡️ mail
- Sinon
- Si tel NON NULL ➡️ tel
- Sinon ➡️
pas de contact
NULLIF
SELECT NULLIF(tel, '00.00.00.00.00')
FROM echecs.joueuse;
- Si tel =
00.00.00.00.00
- Renvoie NULL
10 Divers
Jouer avec les colonnes
SELECT CONCAT(nom, ' ', prenom) AS nom_complet,
eloFROM echecs.joueuse;
nom_complet | elo |
---|---|
Guichard Pauline | 2357 |
Daulyte-Cornette Deimante | 2371 |
Navrotescu Andreea | 2338 |
Sebag Marie | 2448 |
Millet Sophie | 2366 |
Skrichempko Almira | 2361 |
Supprimer les doublons
Le mot clé DISTINCT
permet de supprimer les doublons.
SELECT DISTINCT prenom
FROM echecs.joueuse;
Choix
SELECT CASE WHEN elo > 2400 THEN 'Niveau MI'
WHEN elo > 2200 THEN 'Joueuse très forte'
ELSE 'Joueuse de niveau normal'
END
FROM echecs.joueuse;
Échantillon
Afficher un échantillon aléatoire de 10 % des lignes
SELECT *
FROM echecs.joueuse
10); TABLESAMPLE BERNOULLI(
Et même !?
SELECT 1,
TRUE,
'a',
current_date,
NOW()FROM echecs.joueuse;
11 Résumé
- CREATE / ALTER / DELETE
- INSERT
- SELECT
- WHERE