Comment représenter une valeur que l’on ne connaît pas ?
valeur NULL
Trois sens possibles pour NULL :
valeur inconnue
valeur inapplicable
absence de valeur
Logique 3 états
Avertissement
Chris J. Date a écrit :
La valeur NULL telle qu’elle est implémentée dans
SQL peut poser plus de problèmes qu’elle n’en résout. Son comportement
est parfois étrange et est source de nombreuses erreurs et de
confusions.
Éviter d’utiliser NULL le plus possible
utiliser NULL correctement lorsqu’il le faut
Assignation de NULL
Assignation de NULL pour INSERT et
UPDATE
Explicitement :
NULL est indiqué explicitement dans les
assignations
Implicitement :
la colonne n’est pas affectée par INSERT
et n’a pas de valeur par défaut
Empêcher la valeur NULL
contrainte NOT NULL
Calculs avec NULL
Utilisation dans un calcul
propagation de NULL
NULL est inapplicable
le résultat vaut NULL
NULL et les prédicats
Dans un prédicat du WHERE :
opérateur IS NULL ou IS NOT NULL
AND :
vaut false si NULL AND false
vaut NULL si NULL AND true ou
NULL AND NULL
OR :
vaut true si NULL OR true
vaut NULL si NULL OR false ou
NULL OR NULL
NULL et les agrégats
Opérateurs d’agrégats
ignorent NULL
sauf count(*)
COALESCE
Remplacer NULL par une autre valeur
COALESCE(attribut, ...);
Agrégats
Regroupement de données
Calculs d’agrégats
Regroupement de données
Regroupement de données :
sql GROUP BY expression [, ...]
Chaque groupe de données est ensuite représenté sur une seule
ligne
Permet d’appliquer des calculs sur les ensembles regroupés
comptage, somme, moyenne, etc.
Calculs d’agrégats
Effectuent un calcul sur un ensemble de valeurs
somme, moyenne, etc.
Retournent NULL si l’ensemble est vide
sauf count()
Agrégats simples
Comptage : sql count(expression)
compte les lignes : count(*)
compte les valeurs renseignées : count(colonne)
Valeur minimale : sql min(expression)
Valeur maximale : sql max(expression)
Calculs d’agrégats
Moyenne : sql avg(expression)
Somme : sql sum(expression)
Écart-type : sql stddev(expression)
Variance : sql variance(expression)
Agrégats sur plusieurs
colonnes
Possible d’avoir plusieurs paramètres sur la même fonction
d’agrégat
Quelques exemples
pente : regr_slope(Y,X)
intersection avec l’axe des ordonnées :
regr_intercept(Y,X)
indice de corrélation : corr (Y,X)
Clause HAVING
Filtrer sur des regroupements
HAVING
WHERE s’applique sur les lignes lues
HAVING s’applique sur les lignes groupées
Sous-requêtes
Corrélation requête/sous-requête
Sous-requêtes retournant une seule ligne
Sous-requêtes retournant une liste de valeur
Sous-requêtes retournant un ensemble
Sous-requêtes retournant un ensemble vide ou non-vide
Corrélation
requête/sous-requête
Fait référence à la requête principale
Peut utiliser une valeur issue de la requête principale
Qu’est-ce qu’une
sous-requête ?
Une requête imbriquée dans une autre requête
Le résultat de la requête principale dépend du résultat de la
sous-requête
Encadrée par des parenthèses : ( et )
Utiliser une seule ligne
La sous-requête ne retourne qu’une seule ligne
sinon une erreur est levée
Positionnée
au niveau de la liste des expressions retournées par
SELECT
au niveau de la clause WHERE
au niveau d’une clause HAVING
Utiliser une liste de
valeurs
La sous-requête retourne
plusieurs lignes
sur une seule colonne
Positionnée
avec une clause IN
avec une clause ANY
avec une clause ALL
Clause IN
expression IN (sous-requete)
L’expression de gauche est évaluée et vérifiée avec la liste de
valeurs de droite
IN vaut true
si l’expression de gauche correspond à un élément de la liste de
droite
IN vaut false
si aucune correspondance n’est trouvée et la liste ne contient pas
NULL
IN vaut NULL
si l’expression de gauche vaut NULL
si aucune valeur ne correspond et la liste contient
NULL
Clause NOT IN
expression NOTIN (sous-requete)
L’expression de droite est évaluée et vérifiée avec la liste de
valeurs de gauche
NOT IN vaut true
si aucune correspondance n’est trouvée et la liste ne contient pas
NULL
NOT IN vaut false
si l’expression de gauche correspond à un élément de la liste de
droite
NOT IN vaut NULL
si l’expression de gauche vaut NULL
si aucune valeur ne correspond et la liste contient
NULL
Clause ANY
expression operateur ANY (sous-requete)
L’expression de gauche est comparée au résultat de la sous-requête
avec l’opérateur donné
La ligne de gauche est retournée
si le résultat d’au moins une comparaison est vraie
La ligne de gauche n’est pas retournée
si aucun résultat de la comparaison n’est vrai
si l’expression de gauche vaut NULL
si la sous-requête ramène un ensemble vide
Clause ALL
expression operateur ALL (sous-requete)
L’expression de gauche est comparée à tous les résultats de la
sous-requête avec l’opérateur donné
La ligne de gauche est retournée
si tous les résultats des comparaisons sont vrais
si la sous-requête retourne un ensemble vide
La ligne de gauche n’est pas retournée
si au moins une comparaison est fausse
si au moins une comparaison est NULL
Utiliser un ensemble
La sous-requête retourne
plusieurs lignes
sur plusieurs colonnes
Positionnée au niveau de la clause FROM
Nommée avec un alias de table
Clause EXISTS
EXISTS (sous-requete)
Intéressant avec une corrélation
La clause EXISTS vérifie la présence ou l’absence de
résultats
vrai si l’ensemble est non vide
faux si l’ensemble est vide
Jointures
Conditions de jointure dans JOIN ou dans
WHERE ?
Produit cartésien
Jointure interne
Jointures externes
Jointure ou sous-requête ?
Conditions de
jointure dans JOIN ou dans WHERE ?
Jointure dans clause JOIN
séparation nette jointure et filtrage
plus lisible et maintenable
jointures externes propres
facilite le travail de l’optimiseur
Jointure dans clause WHERE
uistorique
Produit cartésien
Clause CROSS JOIN
Réalise toutes les combinaisons entre les lignes d’une table et les
lignes d’une autre
À éviter dans la mesure du possible
peu de cas d’utilisation
peu performant
Jointure interne
Clause INNER JOIN
meilleure lisibilité
facilite le travail de l’optimiseur
Joint deux tables entre elles
Selon une condition de jointure
Syntaxe d’une jointure
interne
Condition de jointure par prédicats :
sql table1 [INNER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
sql table1 [INNER] JOIN table2 USING (colonne [, ...])
Liste des colonnes de même nom (dangereux) :
sql table1 NATURAL [INNER] JOIN table2
Jointure externe
Jointure externe à gauche
ramène le résultat de la jointure interne
ramène l’ensemble de la table de gauche qui ne peut être joint avec
la table de droite
les attributs de la table de droite sont alors
NULL
Jointure externe - 2
Jointure externe à droite
ramène le résultat de la jointure interne
ramène l’ensemble de la table de droite qui ne peut être joint avec
la table de gauche
les attributs de la table de gauche sont alors
NULL
Jointure externe complète
Ramène le résultat de la jointure interne
Ramène l’ensemble de la table de gauche qui ne peut être joint avec
la table de droite
les attributs de la table de droite sont alors
NULL
Ramène l’ensemble de la table de droite qui ne peut être joint avec
la table de gauche
les attributs de la table de gauche sont alors
NULL
Syntaxe d’une jointure
externe à gauche
Condition de jointure par prédicats :
sql table1 LEFT [OUTER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
sql table1 LEFT [OUTER] JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
sql table1 NATURAL LEFT [OUTER] JOIN table2
Syntaxe d’une jointure
externe à droite
Condition de jointure par prédicats :
sql table1 RIGHT [OUTER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
sql table1 RIGHT [OUTER] JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
sql table1 NATURAL RIGHT [OUTER] JOIN table2
Syntaxe d’une jointure
externe complète
Condition de jointure par prédicats :
sql table1 FULL OUTER JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
sql table1 FULL OUTER JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
sql table1 NATURAL FULL OUTER JOIN table2
Jointure ou sous-requête ?
Jointures
algorithmes très efficaces
ne gèrent pas tous les cas
Sous-requêtes
parfois peu performantes
répondent à des besoins non couverts par les jointures
Expressions CASE
Équivalent à l’instruction switch en C ou Java
Emprunté au langage Ada
Retourne une valeur en fonction du résultat de tests
CASE simple
CASE expressionWHEN valeur THEN expressionWHEN valeur THEN expression (...)ELSE expressionEND
CASE sur expressions
CASEWHEN expression THEN expressionWHEN expression THEN expression (...)ELSE expressionEND
Spécificités de CASE
Comportement procédural
les expressions sont évaluées dans l’ordre d’apparition
Transtypage
le type du retour de l’expression dépend du type de rang le plus
élevé de toute l’expression
Imbrication
des expressions CASE à l’intérieur d’autres expressions
CASE
Clause ELSE
recommandé
Opérateurs ensemblistes
UNION
INTERSECT
EXCEPT
Regroupement de deux
ensembles
Regroupement avec dédoublonnage :
requete_select1 UNION requete_select2
Regroupement sans dédoublonnage :
requete_select1 UNIONALL requete_select2
Intersection de deux
ensembles
Intersection de deux ensembles avec dédoublonnage :
requete_select1 INTERSECT requete_select2
Intersection de deux ensembles sans dédoublonnage :
requete_select1 INTERSECTALL requete_select2
Différence entre deux
ensembles
Différence entre deux ensembles avec dédoublonnage :
requete_select1 EXCEPT requete_select2
Différence entre deux ensembles sans dédoublonnage :
requete_select1 EXCEPTALL requete_select2
Fonctions de base
Transtypage
Manipulation de chaines
Manipulation de types numériques
Manipulation de dates
Génération de jeu de données
Transtypage
Conversion d’un type de données vers un autre type de données
CAST (expression AS type)
expression::type
Opérations simples sur les
chaînes
Concaténation : chaîne1 || chaîne2
Longueur de la chaîne : char_length(chaîne)
Conversion en minuscules : lower(chaîne)
Conversion en majuscules : upper(chaîne)
Manipulations de chaînes
Extrait une chaîne à partir d’une autre :
substring(chaîne [from int] [for int])
Emplacement d’une sous-chaîne :
position(sous-chaîne in chaîne)
Manipulation de types
numériques
Opérations arithmétiques
Manipulation de types numériques
Génération de données
Opérations arithmétiques
Addition : +
Soustraction : -
Multiplication : *
Division : /
entière si implique des entiers !
Reste (modulo) : %
Fonctions numériques
courantes
Arrondi : round(numeric)
Troncature : trunc(numeric [, precision])
Entier le plus petit : floor(numeric)
Entier le plus grand : ceil(numeric)
Génération de données
-- Suite d'entiers, 1 par ligneSELECT i FROM generate_series(0, 100, 1) i ;-- Nombre entre 0 et 1.0SELECTrandom() ;-- Entre 1 et 100SELECT (random()*100)::int ;-- Entre 2 bornes (v17+)SELECTrandom (20.0, 50.0) ; -- numericSELECTrandom (-100, 100) ; -- entier
Manipulation de dates
Obtenir la date et l’heure courante
Manipuler des dates
Opérations arithmétiques
Formatage de données
Date et heure courante
Retourne la date courante : current_date
Retourne l’heure courante : current_time
Retourne la date et l’heure courante :
current_timestamp / now()
Manipulation des données
Âge
Par rapport à la date courante : age(timestamp)
Par rapport à une date de référence :
age(timestamp, timestamp)
Tronquer et extraire
Troncature d’une date :
date_trunc(text, timestamp)
Exemple : date_trunc('month' from date_naissance)
Extrait une composante de la date :
extract(text, timestamp)
Exemple : extract('year' from date_naissance)
Arithmétique sur les dates
Opérations arithmétiques sur timestamp,
time ou date
date/time - date/time = interval
date/time + time = date/time
date/time + interval = date/time
Opérations arithmétiques sur interval
interval * numeric = interval
interval / numeric = interval
interval + interval = interval
Date vers chaîne
Conversion d’une date en chaîne de caractères :
to_char(timestamp, text)
Exemple :
to_char(current_timestamp, 'DD/MM/YYYY HH24:MI:SS')
Chaîne vers date
Conversion d’une chaîne de caractères en date :
to_date(text, text)to_date('05/12/2000', 'DD/MM/YYYY')
Conversion d’une chaîne de caractères en timestamp :
to_timestamp(text, text)to_timestamp('05/12/2000 12:00:00', 'DD/MM/YYYY HH24:MI:SS')