Colonnes calculées SQL, fonctions et CASE

Apprends à calculer de nouvelles colonnes dans des requêtes SQL. Effectue des calculs arithmétiques avec des alias de colonne explicites, convertis des valeurs entre types de données, nettoie et découpe du texte comme des noms et des adresses e-mail, et calcule des dates, des mois, des âges et des échéances. Gère les valeurs manquantes avec la logique de NULL, COALESCE et NULLIF, et répartis les lignes en catégories avec des expressions CASE. Les exemples fonctionnent sur SQLite et PostgreSQL, et les différences que tu rencontreras dans MySQL, SQL Server et Oracle sont signalées au fil du cours.

DébutantUnité 3 sur 6 de la formation Formation : SQL : requêtes SELECT, jointures et agrégation

Ce que tu vas apprendre

  1. Calcule de nouvelles valeurs pour chaque ligne à l’aide d’opérations arithmétiques et de fonctions, donne des noms explicites aux résultats et évite que les types de données ne modifient la réponse.
    • Calculer de nouvelles colonnes et les nommer avec des alias
      Écris des expressions dans la liste SELECT, nomme les résultats avec AS et repère où ces noms peuvent être utilisés dans une requête.
    • Calculer avec les opérateurs arithmétiques et les fonctions numériques
      Utilise +, -, *, / et % dans le bon ordre, évite les surprises liées à la division entière et arrondis les résultats avec ROUND et les fonctions associées.
    • Convertir des valeurs d’un type de données à un autre
      Reconnais le type de chaque valeur, convertis-la explicitement avec CAST et repère les conversions automatiques qui modifient le tri, les comparaisons et les résultats.
  2. Prévois l’effet de NULL sur les calculs, les comparaisons et les filtres, et remplace ou crée délibérément des valeurs manquantes.
    • Prévoir le comportement de NULL dans les calculs et les conditions
      Explique ce que signifie NULL, comment il se propage dans les expressions et pourquoi une condition qui rencontre NULL n’est ni vraie ni fausse.
    • Remplacer et créer des valeurs manquantes avec COALESCE et NULLIF
      Comble les valeurs manquantes avec COALESCE, transforme les zéros et les valeurs factices en NULL avec NULLIF et choisis des valeurs de remplacement qui conservent le sens des données.
  3. Concatène, nettoie, mesure et découpe des valeurs textuelles pour obtenir des noms, des adresses e-mail et des codes cohérents et utilisables.
    • Concaténer et nettoyer des valeurs textuelles
      Concatène du texte, change la casse, supprime les espaces en début et en fin de chaîne et remplace des caractères, puis imbrique ces fonctions pour nettoyer des données saisies de façon irrégulière.
    • Mesurer un texte et en extraire des parties
      Compte les caractères, trouve où apparaît un caractère et découpe des parties de texte à l’aide de positions qui commencent à 1.
  4. Écris et lis correctement des valeurs de date, décompose-les et mets-les en forme, puis effectue des calculs avec des jours, des mois et des durées.
    • Écrire, stocker et lire des valeurs de date et d’heure
      Reconnais les types de date et d’heure, écris les dates au format ISO sans ambiguïté, convertis du texte en dates et obtiens la date et l’heure actuelles.
    • Extraire et mettre en forme des parties de dates
      Extrais l’année, le mois ou le jour de la semaine, regroupe les dates par période et transforme-les en texte lisible.
    • Calculer avec des dates et filtrer des plages de dates
      Ajoute des jours et des mois, mesure le temps entre deux dates et écris des filtres qui incluent toutes les lignes d’une période.
  5. Transforme des conditions en libellés, en catégories et en ordres de tri personnalisés avec CASE, puis combine-le avec les autres fonctions dans des requêtes de rapport complètes.
    • Répartir des lignes en catégories avec un CASE recherché
      Écris CASE WHEN … THEN … ELSE … END, ordonne les conditions pour placer chaque ligne dans le bon groupe et traite les valeurs limites et les NULL.
    • Utiliser le CASE simple et employer CASE dans toute une requête
      Traduis des codes avec le CASE simple, construis des indicateurs et des ordres de tri personnalisés, et reconnais les formes plus courtes proposées par d’autres bases de données.
    • Combiner des fonctions dans une requête de rapport complète
      Construis un rapport avec plusieurs colonnes calculées étape par étape, imbrique correctement les fonctions et vérifie chaque colonne à partir de lignes calculées à la main.

Colonnes calculées SQL : cours

5 chapitres

1

Créer des colonnes calculées avec des expressions et des alias

Les colonnes calculées transforment les valeurs déjà présentes dans une ligne en réponses utiles : le montant d’une ligne, une remise ou un pourcentage de changement. Des alias explicites rendent ces résultats lisibles, tandis que les parenthèses et les types de données déterminent ce que SQL calcule réellement. Tu construiras des expressions par petites étapes, verras pourquoi la division entière peut supprimer une fraction et choisiras des conversions explicites lorsque la forme stockée ne convient pas à l’opération.

1.1 Calculer de nouvelles colonnes et les nommer avec des alias

Une colonne de résultat peut afficher une valeur qui n’est stockée nulle part dans la table. SQL la calcule à partir de la ligne courante. Une expression combine des colonnes, des valeurs fixes, des opérateurs et des appels de fonctions.

Calculer une valeur pour chaque ligne
SELECT order_id,
       quantity * unit_price AS line_total
FROM orders;

Pour une quantité de 3 et un prix unitaire de 12,50, la nouvelle colonne affiche 37.5. Chaque ligne fournit sa propre quantité et son propre prix. La requête laisse les colonnes stockées inchangées. Une fonction monoligne, comme ROUND(unit_price, 0), renvoie aussi une valeur par ligne d’entrée. L’ajouter à la liste SELECT ne combine pas les lignes. Une fonction d’agrégation comme SUM ou AVG calcule quant à elle une valeur pour un groupe.

Le nom après AS est un alias de colonne : un en-tête pour le résultat. Sans lui, SQLite utilise le texte de l’expression comme en-tête ; PostgreSQL utilise ?column? pour cette expression arithmétique. AS est facultatif, mais permet de distinguer plus facilement un nom d’une virgule manquante.

Choisir les noms et les guillemets

Utilise un nom simple comme line_total : des lettres, des chiffres et des tirets bas, en commençant par une lettre. Un nom contenant un espace ou correspondant à un mot réservé doit être entouré de guillemets doubles : AS "Line Total" ou AS "order". Les apostrophes délimitent les valeurs textuelles, comme 'Boston'. MySQL accepte aussi les accents graves pour les noms, et SQL Server accepte les crochets.

PostgreSQL convertit en minuscules les noms sans guillemets : AS LineTotal produit linetotal. Les guillemets doubles conservent la casse dans AS "LineTotal". SQLite conserve un alias tel qu’il est saisi. Les noms en minuscules séparées par des tirets bas conviennent aux deux.

Utiliser un alias à la bonne étape

L’ordre logique est FROM, WHERE, SELECT, puis ORDER BY. La table est choisie et les lignes sont filtrées avant que les expressions de sortie ne reçoivent leurs alias. Le tri a lieu ensuite.

SELECT order_id,
       quantity * unit_price AS line_total
FROM orders
WHERE quantity * unit_price > 100
ORDER BY line_total DESC;

ORDER BY peut utiliser line_total. Le SQL standard, PostgreSQL et MySQL ne peuvent pas utiliser ce nouvel alias dans WHERE ; répète l’expression à cet endroit. SQLite accepte un alias dans WHERE comme extension, mais cette forme échouera si elle est transférée vers PostgreSQL.

Un nouvel alias n’est pas non plus disponible pour une autre expression dans la même liste SELECT. Après unit_price * 1.08 AS with_tax, écrire with_tax - unit_price AS tax échoue si la table ne possède pas de colonne with_tax. Écris plutôt unit_price * 1.08 - unit_price AS tax.

Diagnostiquer un résultat surprenant

SELECT first_name last_name FROM customers; est du SQL valide. Cette requête affiche une colonne de prénoms avec l’alias last_name. Pour extraire les deux colonnes, écris SELECT first_name, last_name FROM customers;. Une virgule manquante peut donc produire un résultat trompeur sans erreur.

Pour vérifier rapidement une expression, une table est inutile : SELECT 19.99 * 3 AS total; renvoie 59.97 dans SQLite et PostgreSQL. Avant Release 23, Oracle exige FROM DUAL pour cette requête ; Release 23 et les versions ultérieures autorisent aussi SELECT sans FROM.

Points clés

  • Une colonne calculée calcule une valeur pour chaque ligne sans modifier les données stockées.
  • Une fonction monoligne conserve les lignes ; un agrégat combine les valeurs d’un groupe.
  • Utilise des guillemets doubles pour les noms qui doivent être délimités et des apostrophes pour les valeurs textuelles.
  • ORDER BY peut utiliser un alias de sortie ; répète l’expression dans une clause WHERE portable.
  • Un nouvel alias n’est pas disponible ailleurs dans la même liste SELECT.
  • Une virgule manquante peut transformer le nom de colonne suivant en alias.

1.2 Calculer avec les opérateurs arithmétiques et les fonctions numériques

Les expressions arithmétiques transforment des quantités brutes en montants, en taux et en différences. Les opérateurs sont +, -, *, / et % ; le modulo donne le reste de la division.

Maîtriser l’ordre des calculs

La multiplication, la division et le modulo viennent avant l’addition et la soustraction. Les opérateurs de même priorité s’exécutent de gauche à droite. Ainsi, 10 + 3 * 2 donne 16, tandis que (10 + 3) * 2 donne 26.

Pour une quantité de 3, un prix unitaire de 12,50 et un pourcentage de remise de 10 :

quantity * unit_price * (1 - discount_pct / 100.0)

D’abord, 10 / 100.0 donne 0.1. Les parenthèses donnent la fraction payée, 0.9. Le montant brut est 37.5, donc le montant net est 33.75. Sans parenthèses, quantity * unit_price * 1 - discount_pct / 100.0 soustrait 0.1 de 37.5 et donne 37.4.

Conserver les fractions pendant la division

Dans SQLite, PostgreSQL et SQL Server, la division de deux entiers supprime la partie fractionnaire par troncation vers zéro : 7 / 2 donne 3, et -7 / 2 donne -3. MySQL et Oracle donnent un résultat décimal pour /. Dans SQLite et PostgreSQL, rends un opérande décimal avant de diviser : 7 / 2.0, 7 * 1.0 / 2 ou CAST(7 AS REAL) / 2 donne 3.5. Avec CAST(7 / 2 AS REAL), la conversion arrive trop tard et donne 3.0.

Pour une hausse de 80 à 92, (92 - 80) * 100.0 / 80 donne 15.0 pour cent. Diviser d’abord la différence entière par 80 fait perdre la fraction. Le modulo conserve le reste : 135 / 60 vaut 2 heures et 135 % 60 vaut 15 minutes. Dans SQLite et PostgreSQL, -7 % 3 donne -1 ; le reste prend le signe de l’opérande de gauche. Oracle écrit MOD(17, 5) à la place de %.

Un diviseur nul produit une erreur dans PostgreSQL et SQL Server ; SQLite et MySQL renvoient NULL. amount / NULLIF(divisor, 0) fait renvoyer NULL dans le cas d’un diviseur nul sur ces systèmes.

Arrondir ou choisir un entier

ROUND(x, n) arrondit à n décimales. Une lampe vendue 24,00 et coûtant 15,50 dégage un bénéfice de 8.5. ROUND((price - cost) / price * 100, 1) donne une marge de 35.4 pour cent. PostgreSQL accepte un nombre de décimales négatif : ROUND(1234.5678, -2) donne 1200 ; SQLite traite ce nombre comme zéro et donne 1235.0.

FonctionSignificationExemple
ABSDistance à zéroABS(-4.2) donne 4.2
CEILPlus petit entier supérieur ou égal à la valeurCEIL(4.1) donne 5
FLOORPlus grand entier inférieur ou égal à la valeurFLOOR(-4.1) donne -5
TRUNCSupprime la partie fractionnaire par troncation vers zéroTRUNC(42.8) donne 42

PostgreSQL fournit ces fonctions. SQLite fournit ABS ; CEIL, FLOOR et TRUNC exigent une version compilée avec les fonctions mathématiques, disponibles à partir de la version 3.35.

Adapter la précision aux données

ROUND dans SQLite et ROUND pour le type numeric de PostgreSQL arrondissent les valeurs exactement à mi-chemin en s’éloignant de zéro : ROUND(-2.5) donne -3. Dans PostgreSQL, l’arrondi des nombres à virgule flottante arrondit généralement les valeurs à mi-chemin à l’entier pair le plus proche ; sa fonction ROUND à deux arguments exige numeric, utilise donc ROUND(CAST(x AS numeric), 2) pour une colonne à double précision.

Les nombres à virgule flottante représentent de nombreuses fractions décimales de façon approximative. Dans SQLite, 0.1 + 0.2 = 0.3 peut être faux et ROUND(2.675, 2) peut renvoyer 2.67. Les littéraux décimaux de PostgreSQL utilisent le type exact numeric. Pour des montants exacts, utilise NUMERIC/DECIMAL dans PostgreSQL ou des centimes entiers dans SQLite. Déclarer DECIMAL dans SQLite ne crée pas de stockage décimal exact. Garde toutes les décimales pendant les calculs et arrondis pour l’affichage.

Points clés

  • Les parenthèses déterminent quels montants sont combinés avant une multiplication ou une division.
  • Convertis un opérande avant la division entière ; convertir le résultat ne peut pas restaurer les chiffres perdus.
  • Le modulo renvoie un reste, comme les minutes qui restent après les heures entières.
  • ROUND, FLOOR, CEIL et TRUNC traitent une valeur fractionnaire de différentes façons.
  • L’arrondi des nombres à virgule flottante et les fonctions numériques disponibles dépendent du type et de la base de données.
  • Utilise un stockage numérique exact dans PostgreSQL ou des centimes entiers dans SQLite pour les montants exacts.
  • NULLIF peut faire qu’un diviseur nul produise NULL au lieu d’une erreur.

1.3 Convertir des valeurs d’un type de données à un autre

Le type de données d’une valeur influe sur les opérations arithmétiques, les comparaisons et le tri. Le nombre 42 est différent du texte '42', même lorsqu’une grille de résultats les affiche de la même façon.

Convertir explicitement une valeur

Parmi les types courants figurent INTEGER pour les entiers, NUMERIC ou DECIMAL pour les décimaux exacts dans PostgreSQL, REAL ou double precision pour les nombres approximatifs, TEXT ou VARCHAR pour le texte, ainsi que DATE, TIME, TIMESTAMP et BOOLEAN lorsqu’ils sont pris en charge.

SELECT CAST('42' AS INTEGER) AS number_value,
       CAST(42 AS TEXT) AS text_value;

CAST(expression AS type) fait partie du SQL standard. Le premier résultat est un nombre ; le second est du texte. PostgreSQL accepte aussi '42'::integer. Convertir NULL donne toujours NULL.

Pour une division décimale dans SQLite, écris CAST(quantity AS REAL) / 4 ; dans PostgreSQL, écris CAST(quantity AS NUMERIC) / 4. Une quantité de 7 donne 1.75. Dans SQLite, CAST(7 AS NUMERIC) / 2 donne toujours 3 : NUMERIC laisse cette valeur entière stockée comme un entier. REAL est le type de conversion adapté à cet usage dans SQLite.

Comprendre l’effet d’une conversion en entier
Entrée et conversionSQLitePostgreSQL
CAST(3.9 AS INTEGER)34
CAST(-3.9 AS INTEGER)-3-4
CAST('abc' AS INTEGER)0Erreur

SQLite supprime la partie fractionnaire par troncation vers zéro. PostgreSQL arrondit une valeur numérique à l’entier le plus proche. Utilise d’abord ROUND, TRUNC, FLOOR ou CEIL lorsque la règle choisie compte. PostgreSQL refuse un texte qui n’est pas un nombre valide. SQLite lit une partie numérique initiale : '12abc' devient 12 et '12.5' devient 12 lors d’une conversion en INTEGER. Un zéro obtenu après une conversion dans SQLite ne prouve donc pas que le texte d’origine était un zéro valide. TRY_CAST dans SQL Server renvoie NULL lorsqu’une conversion échoue.

Distinguer les quantités des identifiants

Le texte est trié caractère par caractère. Les chaînes '9', '10' et '100' sont triées dans l’ordre '10', '100', '9'. Pour classer de véritables quantités numériques conservées sous forme de texte, utilise ORDER BY CAST(code AS INTEGER) après t’être assuré que ce sont des nombres valides.

Un code postal américain comme '02134' est un identifiant. Le convertir donne 2134 et fait perdre le premier zéro. Les numéros de téléphone doivent aussi être du texte : leurs chiffres servent à identifier quelque chose, plutôt qu’à décrire une quantité à additionner ou dont calculer la moyenne.

Reconnaître les conversions automatiques

SQLite et PostgreSQL convertissent tous deux le nombre en texte dans 'Order #' || 42, ce qui produit 'Order #42'. Tous deux évaluent aussi le littéral entre apostrophes dans '5' + 3 comme un nombre. Dans PostgreSQL, ce littéral a initialement un type non fixé ; une colonne TEXT n’a pas la même liberté. Ajouter 3 à une colonne TEXT échoue : convertis donc explicitement la colonne.

SQLite attribue aux colonnes une préférence de type, appelée affinité de type, et peut conserver différents types de valeurs dans une même colonne ordinaire. typeof(42), typeof(4.2), typeof('42') et typeof(NULL) indiquent 'integer', 'real', 'text' et 'null'. SQLite n’a pas de type DATE dédié : CAST('2026-03-14' AS DATE) donne 2026. Utilise date('2026-03-14') avec ses fonctions de date.

Oracle fournit TO_NUMBER, TO_CHAR et TO_DATE. TO_CHAR et TO_DATE dans PostgreSQL prennent des modèles de format comme 'MM/DD/YYYY'. CONVERT dans SQL Server utilise un code de style numérique : CONVERT(date, '03/14/2026', 101) lit le format de date américain.

Points clés

  • CAST convertit explicitement une valeur dans le type demandé ; NULL reste NULL.
  • SQLite tronque les valeurs numériques converties en entiers, tandis que PostgreSQL les arrondit.
  • SQLite peut convertir un texte numérique invalide en un nombre partiel ou en zéro.
  • Conserve les codes postaux américains et les numéros de téléphone sous forme de texte pour préserver leur identité.
  • Le tri des textes et celui des nombres peuvent donner des ordres différents.
2

Gérer les valeurs manquantes avec la logique de NULL et COALESCE

Une valeur manquante peut modifier un calcul ainsi que les lignes conservées par un filtre. Pour comprendre NULL, il faut suivre à la fois les données et la condition qui les utilise. Tu distingueras une valeur manquante de zéro et d’une chaîne vide, suivras TRUE, FALSE et UNKNOWN dans une requête et choisiras des valeurs de repli qui préservent le sens d’un rapport. COALESCE et NULLIF te permettront ensuite de combler des valeurs manquantes ou d’en créer délibérément.

2.1 Prévoir le comportement de NULL dans les calculs et les conditions

NULL indique une valeur manquante ou inconnue. Une cellule de résultat vide peut afficher NULL, mais NULL n’est pas une valeur ordinaire que l’on compare avec =.

Suivre une entrée manquante dans une expression

Zéro est un nombre connu. La chaîne vide '' est une chaîne connue sans caractère. Le texte 'N/A' est un libellé enregistré. NULL indique qu’aucune valeur n’est disponible. Oracle traite la chaîne vide comme NULL ; SQLite et PostgreSQL les distinguent.

La plupart des opérations arithmétiques et des fonctions transmettent une entrée manquante sous la forme NULL. Avec un salaire de 50 000 et une prime NULL, salary + bonus donne NULL. Le total est inconnu parce que la prime est inconnue. UPPER(NULL), ROUND(NULL, 2) et 'Ana ' || NULL renvoient aussi NULL dans SQLite et PostgreSQL.

Tester directement NULL

bonus = NULL, bonus <> NULL et même NULL = NULL produisent UNKNOWN. On ne sait pas si deux valeurs manquantes sont égales. Utilise bonus IS NULL ou bonus IS NOT NULL. Ces tests renvoient toujours TRUE ou FALSE.

Les conditions SQL ont trois résultats possibles : TRUE, FALSE et UNKNOWN. SQLite affiche TRUE sous la forme 1, FALSE sous la forme 0 et UNKNOWN sous la forme NULL.

ConditionRésultatRaison
FALSE AND UNKNOWNFALSEUne condition fausse suffit à rendre AND faux
TRUE AND UNKNOWNUNKNOWNLa deuxième condition reste indéterminée
TRUE OR UNKNOWNTRUEUne possibilité vraie suffit à rendre OR vrai
FALSE OR UNKNOWNUNKNOWNLa possibilité restante reste indéterminée
NOT UNKNOWNUNKNOWNInverser une valeur inconnue ne la détermine pas
Comprendre les lignes conservées par WHERE

WHERE ne conserve que TRUE. FALSE et UNKNOWN excluent tous deux la ligne. Pour les primes 1 000, 0, NULL, 2 500 et NULL, WHERE bonus < 1000 ne conserve que le zéro. WHERE bonus >= 1000 conserve 1 000 et 2 500. Ces filtres couvrent trois lignes, et non cinq. WHERE NOT (bonus < 1000) ne conserve aussi que les deux primes connues d’au moins 1 000.

Le même problème concerne <>. Avec les villes Boston, Denver, NULL, Boston et Austin, WHERE city <> 'Boston' conserve Denver et Austin. Inclus explicitement la ville inconnue :

WHERE city <> 'Boston' OR city IS NULL

Cette condition conserve trois lignes. NOT ne réintègre pas automatiquement les valeurs manquantes.

Surveiller les listes et les comparaisons

3 IN (1, 2, NULL) vaut UNKNOWN : l’élément manquant pourrait être 3. Pour x NOT IN (1, 2, NULL), une valeur correspondante ne passe pas le test NOT IN et toute valeur sans correspondance donne UNKNOWN. Dans une clause WHERE, cette liste fixe ne conserve aucune ligne. Supprime tout NULL involontaire d’une liste d’exclusion avant de l’utiliser.

Pour une égalité qui considère deux NULL comme égaux, utilise a IS NOT DISTINCT FROM b. Son contraire, a IS DISTINCT FROM b, vaut TRUE lorsqu’une valeur est NULL et que l’autre ne l’est pas ; deux NULL ne sont pas distincts. PostgreSQL et SQLite à partir de la version 3.39 prennent en charge ces formes. SQLite possède aussi IS et IS NOT ; MySQL écrit l’égalité sûre avec NULL sous la forme <=>.

Le placement des NULL par défaut diffère selon la base : SQLite place NULL en premier dans l’ordre croissant ; PostgreSQL le place en dernier. Précise le placement lorsqu’il compte : ORDER BY bonus DESC NULLS LAST place les primes connues par ordre décroissant et les primes manquantes à la fin.

Points clés

  • NULL indique une valeur manquante ou inconnue, et non zéro ou une chaîne vide.
  • Les comparaisons avec NULL produisent UNKNOWN ; teste les valeurs manquantes avec IS NULL.
  • WHERE ne conserve que TRUE : NOT et <> ne réintègrent donc pas les lignes dont le résultat est inconnu.
  • AND et OR ne peuvent déterminer un résultat inconnu que si l’autre condition décide du résultat.
  • Un NULL dans une liste NOT IN empêche cette condition de valoir TRUE.
  • IS NOT DISTINCT FROM considère deux NULL comme égaux.
  • NULLS FIRST ou NULLS LAST rend le placement dans le tri explicite.

2.2 Remplacer et créer des valeurs manquantes avec COALESCE et NULLIF

Les valeurs manquantes ont parfois besoin d’une valeur de repli et doivent parfois rester manquantes. Ce choix fait partie du sens d’un rapport. COALESCE comble une valeur manquante ; NULLIF transforme une valeur factice correspondante en valeur manquante.

Choisir la première valeur disponible

COALESCE(a, b, ...) examine les arguments de gauche à droite et renvoie le premier qui n’est pas NULL. La fonction renvoie NULL si tous les arguments sont NULL.

SELECT COALESCE(mobile_phone, home_phone, 'no phone') AS contact
FROM customers;

Sans numéro de portable et avec le numéro fixe '555-0100', le contact est '555-0100'. Si aucun des deux numéros n’est enregistré, c’est 'no phone'. Un zéro connu ou une chaîne vide compte comme disponible : COALESCE ignore NULL, pas les valeurs qui semblent vides ou fausses.

Pour la rémunération, salary + COALESCE(bonus, 0) donne 50 000 lorsque le salaire est de 50 000 et que la prime vaut NULL. Cela convient si une prime manquante signifie qu’aucune prime n’a été versée. Une note de produit manquante ne signifie pas une note de zéro ; la remplacer inventerait une mauvaise note. Laisse ce nombre manquant ou crée un libellé textuel pour l’affichage.

Garder des types compatibles pour les valeurs de repli

PostgreSQL ne peut pas combiner l’entier rating et le texte 'not rated' dans un même résultat numérique. Convertis d’abord les notes connues en texte :

COALESCE(CAST(rating AS TEXT), 'not rated')

Une note de 4 s’affiche sous forme du texte '4' ; un NULL s’affiche sous la forme 'not rated'. SQLite accepte des arguments numériques et textuels mélangés, mais la sortie peut alors contenir différents types. Rends le type de résultat attendu explicite lorsque tu transfères une requête d’une base à une autre.

COALESCE fait partie du SQL standard et accepte au moins deux arguments. Les variantes courantes à deux arguments sont IFNULL dans SQLite et MySQL, ISNULL dans SQL Server et NVL dans Oracle.

Transformer une valeur factice en NULL

NULLIF(a, b) renvoie NULL si les arguments sont égaux ; sinon, la fonction renvoie le premier argument. NULLIF(0, 0) vaut NULL, tandis que NULLIF(5, 0) vaut 5.

Voici une expression utile pour calculer un taux :

orders * 100.0 / NULLIF(visits, 0) AS conversion_pct

Avec 12 commandes et 300 visites, le diviseur reste égal à 300 et le taux est 4.0. Avec zéro visite, le diviseur devient NULL et le taux devient NULL. PostgreSQL évite une erreur de division par zéro et le résultat indique correctement un taux indéfini. Remplacer ce taux par zéro exprimerait une autre affirmation.

Nettoyer les valeurs manquantes avant de fournir un libellé
COALESCE(NULLIF(phone, ''), 'unknown')

Le NULLIF intérieur transforme une chaîne vide en NULL. Le COALESCE extérieur attribue ensuite le libellé 'unknown' aussi bien à un NULL d’origine qu’à une chaîne vide. Un numéro de téléphone enregistré est conservé tel quel.

Pour un deuxième prénom facultatif, inclus l’espace qui le suit dans la valeur de repli :

first_name || ' ' || COALESCE(middle_name || ' ', '') || last_name

Un deuxième prénom NULL n’ajoute rien, ce qui produit 'Ana Lopez'. Un deuxième prénom 'Maria' ajoute 'Maria ', ce qui produit 'Ana Maria Lopez'.

Ces expressions ne modifient que le résultat de la requête. Elles laissent les valeurs d’origine stockées dans la table. Un filtre comme WHERE COALESCE(bonus, 0) = 0 regroupe les primes connues égales à zéro et les primes manquantes ; utilise-le donc lorsque ce sont les deux groupes recherchés.

Points clés

  • COALESCE renvoie le premier argument qui n’est pas NULL, y compris un zéro connu ou une chaîne vide.
  • Une valeur de repli doit exprimer le sens des données manquantes et avoir un type compatible.
  • NULLIF renvoie NULL en cas d’égalité et son premier argument sinon.
  • Utilise NULLIF autour d’un diviseur pour qu’un dénominateur nul produise NULL.
  • Nettoie une valeur factice avec NULLIF avant d’appliquer une valeur de repli pour l’affichage avec COALESCE.
3

Nettoyer, combiner et découper du texte avec les fonctions de chaînes

Le texte d’une table doit souvent être rendu utilisable : un nom complet, une adresse e-mail cohérente ou une partie de code. SQL peut concaténer et nettoyer des chaînes, compter leurs caractères et extraire la partie située avant ou après un séparateur. Tu suivras les positions des caractères à chaque étape et vérifieras l’effet des espaces, de la casse et de NULL sur le résultat. SQLite et PostgreSQL partagent de nombreuses fonctions, mais plusieurs noms et comportements diffèrent.

3.1 Concaténer et nettoyer des valeurs textuelles

SQL traite une valeur textuelle comme une chaîne de caractères. Les fonctions de texte peuvent construire un nom complet ou nettoyer une adresse e-mail pour la comparer. Leurs résultats apparaissent dans la requête ; le texte stocké reste inchangé.

Écrire et concaténer du texte

Les littéraux textuels utilisent des apostrophes. Pour inclure une apostrophe, double-la : 'O''Brien' représente « O'Brien ». Une paire d’apostrophes, '', est une chaîne vide.

SELECT first_name || ' ' || last_name AS full_name
FROM customers;

L’opérateur de concaténation || assemble les parties exactement telles qu’elles sont écrites. Avec 'Ana' et 'Lopez', le résultat est 'Ana Lopez'. Le littéral du milieu fournit l’espace ; la concaténation n’en insère pas automatiquement.

SQLite, PostgreSQL et Oracle utilisent ||. Dans MySQL, || signifie OR par défaut : utilise donc CONCAT. SQL Server utilise + et prend aussi en charge || à partir de 2025. Pour concaténer un identifiant numérique de commande, SQLite et PostgreSQL le convertissent en texte dans 'Order #' || order_id. Avec le + de SQL Server, convertis d’abord le nombre : 'Order #' + CAST(order_id AS VARCHAR(10)).

Choisir comment concaténer une partie manquante

Dans SQLite et PostgreSQL, un opérande NULL rend le résultat de || NULL. Oracle traite cette partie manquante comme une chaîne vide. CONCAT diffère aussi selon la base de données :

Base de donnéesCONCAT('Ana', NULL, 'Lopez')
PostgreSQL, SQL Server, SQLite à partir de la version 3.44'AnaLopez'
MySQLNULL

CONCAT dans Oracle prend exactement deux arguments. CONCAT_WS(' ', first_name, middle_name, last_name) place des espaces entre les parties qui ne sont pas NULL, donc un deuxième prénom manquant donne 'Ana Lopez'. SQLite a ajouté CONCAT et CONCAT_WS dans la version 3.44. Ignorer NULL ne supprime toutefois pas une chaîne vide.

Changer la casse et supprimer les espaces aux extrémités

UPPER('boston') donne 'BOSTON' ; LOWER produit des minuscules. INITCAP('ana LOPEZ') dans PostgreSQL donne 'Ana Lopez'. SQLite n’a pas INITCAP, et son changement de casse intégré ne modifie que les lettres de A à Z : UPPER('é') reste 'é' sans l’extension ICU. Le changement de casse dans PostgreSQL suit ses paramètres régionaux.

TRIM supprime les espaces aux deux extrémités ; LTRIM les supprime seulement au début et RTRIM seulement à la fin. TRIM(' New York ') donne 'New York', en conservant les deux espaces intérieurs. Pour supprimer x aux deux extrémités, SQLite écrit TRIM('xxBostonxx', 'x') ; PostgreSQL écrit TRIM(BOTH 'x' FROM 'xxBostonxx').

Remplacer des caractères et imbriquer les étapes de nettoyage

REPLACE('555-0100', '-', '') donne '5550100'. La fonction remplace chaque occurrence exacte. La casse compte : remplacer 'st' dans 'Main St' ne change rien, car 'St' comporte un S majuscule.

SELECT LOWER(TRIM(email)) AS email_clean
FROM customers;

Pour ' Ana@Example.COM ', TRIM produit d’abord 'Ana@Example.COM', puis LOWER produit 'ana@example.com'. L’imbrication signifie que la fonction la plus intérieure fournit l’entrée de la suivante.

La comparaison ordinaire de textes par égalité distingue par défaut les majuscules des minuscules dans SQLite et PostgreSQL. WHERE LOWER(TRIM(email)) = 'ana@example.com' peut trouver une correspondance avec une entrée dont la casse diffère et qui comporte des espaces aux extrémités. La collation par défaut de MySQL ignore la casse, et LIKE dans SQLite ignore la casse des lettres de A à Z, même si sa comparaison = par défaut ne l’ignore pas.

Points clés

  • Utilise des apostrophes pour le texte et double toute apostrophe à l’intérieur d’un littéral.
  • La concaténation assemble les parties exactes ; inclus explicitement les séparateurs.
  • Le comportement de NULL diffère entre ||, CONCAT et les dialectes des bases de données.
  • TRIM supprime les espaces aux extrémités, tandis que REPLACE modifie les caractères correspondants partout dans le texte.
  • Les fonctions imbriquées s’exécutent de l’intérieur vers l’extérieur.
  • Le changement de casse et les comparaisons qui en tiennent compte dépendent de la base de données et des paramètres régionaux.

3.2 Mesurer un texte et en extraire des parties

Les fonctions de texte repèrent et découpent des parties selon la position des caractères. En SQL, les positions commencent à 1 : le premier caractère est donc à la position 1. Une position trouvée et un nombre de caractères sont deux entrées différentes.

Mesurer et découper une chaîne

LENGTH('Boston') donne 6. Les espaces comptent : LENGTH(' Bo ') donne 4. Une chaîne vide a une longueur de 0 ; LENGTH(NULL) vaut NULL. Dans MySQL, LENGTH compte les octets : utilise donc CHAR_LENGTH pour compter les caractères. SQL Server utilise LEN, qui ignore les espaces en fin de chaîne.

SELECT SUBSTR('Boston', 1, 3) AS beginning,
       SUBSTR('Boston', 4) AS ending;

Les résultats sont 'Bos' et 'ton'. Le premier appel prend trois caractères à partir de la position 1. Le second omet le nombre de caractères et prend tout à partir de la position 4. PostgreSQL écrit aussi SUBSTRING('Boston' FROM 4 FOR 3). SQLite accepte le nom SUBSTRING à partir de la version 3.34. SQL Server utilise SUBSTRING(text, start, count) ; le nombre de caractères est obligatoire jusqu’à la version 2022 et facultatif à partir de 2025.

SQLite peut compter depuis la droite : SUBSTR('Boston', -3) donne 'ton'. Dans PostgreSQL, une position de départ négative ne compte pas à rebours depuis la fin. Utilise RIGHT('Boston', 3) ; LEFT prend les caractères depuis le début. SQLite n’a ni LEFT ni RIGHT.

Trouver le point de séparation

INSTR(text, search) dans SQLite renvoie la position de la première correspondance. PostgreSQL utilise STRPOS ou POSITION(search IN text). Ces fonctions renvoient 0 si aucune correspondance n’est trouvée. La recherche distingue les majuscules des minuscules : INSTR('Ana', 'a') vaut 3.

Dans 'ana@example.com', le @ est à la position 4. Le nom d’utilisateur se termine juste avant ; le domaine commence juste après :

SUBSTR(email, 1, INSTR(email, '@') - 1) AS user_name,
SUBSTR(email, INSTR(email, '@') + 1) AS domain

La première expression devient SUBSTR(email, 1, 3) et produit 'ana'. La seconde commence à 5 et produit 'example.com'. Omettre - 1 inclut @ dans le nom d’utilisateur. Omettre + 1 l’inclut au début du domaine. Dans PostgreSQL, remplace INSTR par STRPOS ou utilise SPLIT_PART(email, '@', 2) pour le domaine.

Gérer un séparateur manquant

Pour 'anaexample.com', INSTR renvoie 0. La formule du domaine commence à 1 et renvoie toute la chaîne, ce qui est trompeur. La formule du nom d’utilisateur dans SQLite donne une chaîne vide ; PostgreSQL refuse la longueur négative de la sous-chaîne. Protège l’extraction :

CASE
  WHEN INSTR(email, '@') > 0
  THEN SUBSTR(email, INSTR(email, '@') + 1)
END

Cette expression renvoie NULL lorsque le séparateur est absent. La vérification porte sur la présence d’un séparateur, pas sur toutes les règles de validité d’une adresse e-mail.

Construire des libellés courts et des codes de largeur fixe

SUBSTR(first_name, 1, 1) || '. ' || last_name donne 'A. Lopez' pour Ana Lopez. WHERE LENGTH(zip_code) <> 5 trouve les chaînes enregistrées comme codes postaux américains dont la longueur est incorrecte ; les longueurs NULL produisent UNKNOWN et sont exclues.

LPAD('42', 5, '0') dans PostgreSQL donne '00042' ; RPAD ajoute des caractères à droite. SQLite peut construire ce code avec SUBSTR('00000' || 42, -5). Ne garder que cinq caractères tronque aussi une valeur plus longue : cette expression à largeur fixe exige donc un code qui y tient.

Points clés

  • Les positions dans les chaînes SQL commencent à 1 ; LENGTH compte les espaces.
  • SUBSTR prend une position de départ et un nombre facultatif de caractères.
  • INSTR, STRPOS et POSITION renvoient 0 en l’absence de correspondance.
  • Utilise la position moins 1 avant un séparateur et la position plus 1 après.
  • Vérifie si le séparateur est absent avant d’extraire une partie.
  • L’extraction depuis la fin et le remplissage portent des noms différents dans SQLite et PostgreSQL.
4

Manipuler des dates et des heures

Le travail sur les dates commence par une distinction claire entre un jour du calendrier, une heure et un horodatage. SQL peut ensuite créer des libellés de mois, calculer des échéances, mesurer le temps écoulé et filtrer une période complète. Tu distingueras les valeurs de date du texte d’affichage, tiendras compte des fins de mois et des anniversaires et compareras les expressions SQLite et PostgreSQL qui accomplissent une même tâche. Les cas limites rendent ces calculs fiables.

4.1 Écrire, stocker et lire des valeurs de date et d’heure

Il est plus facile de calculer avec une date lorsque son stockage et son écriture sont clairs. Le texte '03/04/2026' pourrait signifier le 4 mars ou le 3 avril. Une date ISO, '2026-03-14', place l’année, le mois et le jour dans un ordre sans ambiguïté.

Associer la valeur à son type

PostgreSQL possède DATE pour un jour du calendrier, TIME pour une heure de la journée et TIMESTAMP pour une date et une heure. Son type TIMESTAMP WITH TIME ZONE, aussi appelé timestamptz, stocke un instant en UTC et l’affiche dans le fuseau horaire de la session. Un TIMESTAMP simple n’inclut pas cette information de fuseau.

SQLite stocke les dates et les heures sous forme de texte ISO ou de nombres, sans types dédiés aux dates et aux heures. Les formes numériques comprennent les jours juliens et le temps Unix. Les fonctions de date interprètent ces valeurs et renvoient une date, une heure ou une mesure numérique.

Utilise du texte ISO de largeur fixe comme '2026-03-14', avec les zéros initiaux. Ajoute une heure au format 24 heures : '2026-03-14 09:30:00'. Le littéral typé DATE '2026-03-14' de PostgreSQL crée explicitement une date.

Préserver l’ordre chronologique

Le texte ISO de largeur fixe se compare dans l’ordre des dates, car il commence par la plus grande composante. '2026-03-14' vient avant '2026-11-02'. Le texte au format d’affichage américain n’a pas cette propriété : en tant que chaînes, '11/02/2025' est trié après '03/14/2026', même si sa date est antérieure.

L’analyseur de SQLite exige un format pris en charge. date('2026-3-14') renvoie NULL parce que le mois ne comporte pas deux chiffres. Il peut aussi normaliser une date impossible : date('2026-02-30') renvoie '2026-03-02'. Un résultat qui n’est pas NULL ne prouve pas à lui seul que l’entrée était un jour valide du calendrier. PostgreSQL rejette DATE '2026-02-30'.

Lire du texte dans un autre format

PostgreSQL et Oracle utilisent TO_DATE('03/14/2026', 'MM/DD/YYYY') pour lire un format américain. PostgreSQL lit aussi le texte ISO avec CAST('2026-03-14' AS DATE) ou '2026-03-14'::date.

SQLite n’a pas d’analyseur TO_DATE. Pour du texte de format fixe MM/DD/YYYY dans d, reconstruis le texte ISO :

SUBSTR(d, 7, 4) || '-' ||
SUBSTR(d, 1, 2) || '-' || SUBSTR(d, 4, 2)

Les parties sont l’année '2026', le mois '03' et le jour '14'. Le résultat est '2026-03-14', que les fonctions de date de SQLite peuvent lire. Ces positions supposent que l’entrée utilise effectivement le format fixe.

Obtenir la date et l’heure actuelles

CURRENT_DATE et CURRENT_TIMESTAMP fonctionnent dans SQLite et PostgreSQL. SQLite renvoie du texte en UTC ; date('now', 'localtime') donne la date locale. Près de minuit, la date UTC et la date locale peuvent différer.

PostgreSQL utilise le fuseau horaire de la session. CURRENT_TIMESTAMP et NOW() correspondent au début de la transaction en cours : attendre dans cette transaction ne fait donc pas avancer leur valeur. MySQL propose NOW() et CURDATE() ; SQL Server possède GETDATE() et SYSDATETIME() ; Oracle possède SYSDATE, qui comprend une heure, et CURRENT_DATE.

Pour vérifier le calcul d’une échéance, utilise d’abord une date de référence fixe comme DATE '2026-10-21' dans PostgreSQL ou '2026-10-21' dans SQLite. Tu peux alors comparer le résultat à un calendrier sans que la réponse change le lendemain.

Points clés

  • DATE représente un jour du calendrier ; TIMESTAMP y ajoute une heure.
  • Utilise AAAA-MM-JJ de largeur fixe pour écrire des dates portables et sans ambiguïté.
  • Le texte ISO se trie chronologiquement lorsque son format et sa référence temporelle sont cohérents.
  • SQLite peut normaliser une date impossible au lieu de la rejeter.
  • Les fonctions de date actuelle suivent des règles différentes pour les fuseaux horaires et les transactions.

4.2 Extraire et mettre en forme des parties de dates

Extrais une composante de date lorsque tu as besoin d’une année ou d’un jour de la semaine pour calculer. Mets une date en forme lorsque tu as besoin de texte pour un lecteur. Ces opérations peuvent produire des types différents, même si les caractères affichés se ressemblent.

Extraire une année, un mois ou un jour de la semaine

PostgreSQL utilise la forme standard EXTRACT(part FROM value). Pour DATE '2026-03-14', l’extraction de YEAR donne 2026 et celle de MONTH donne 3, tous deux sous forme de nombres. MySQL et Oracle prennent aussi en charge EXTRACT.

SQLite utilise strftime(format, value), qui renvoie du texte :

Modèle SQLiteRésultat pour '2026-03-14'
'%Y''2026'
'%m''03'
'%d''14'
'%w''6'

Le %w de SQLite et le DOW de PostgreSQL numérotent les jours de 0 pour le dimanche à 6 pour le samedi. Le 14 mars 2026 est un samedi. ISODOW dans PostgreSQL les numérote de 1 pour le lundi à 7 pour le dimanche. Un filtre de week-end dans SQLite est WHERE strftime('%w', order_date) IN ('0', '6').

Comparer les bons types

strftime('%m', order_date) = 3 est faux pour une date de mars dans SQLite : la fonction renvoie le texte '03', et non le nombre 3. Compare-le avec = '03' ou convertis-le d’abord :

CAST(strftime('%m', order_date) AS INTEGER) = 3

C’est aussi utile dans l’expression du trimestre (CAST(strftime('%m', d) AS INTEGER) + 2) / 3. La division entière donne le trimestre 1 pour mars et le trimestre 4 pour novembre. PostgreSQL possède directement EXTRACT(QUARTER FROM d).

Identifier un mois comme une période entière

strftime('%Y-%m', order_date) crée un libellé SQLite comme '2026-03'. date(order_date, 'start of month') crée '2026-03-01'. PostgreSQL peut utiliser TO_CHAR(order_date, 'YYYY-MM') pour un libellé ou DATE_TRUNC('month', order_date) pour le premier instant de ce mois.

Conserve l’année dans un libellé de période. La seule valeur de mois 3 réunirait les mois de mars de différentes années. La valeur correspondant au premier jour du mois peut rester la valeur utilisée pour les calculs et le tri, tandis qu’une expression distincte fournit l’affichage.

Mettre en forme à l’étape de sortie

Dans PostgreSQL, TO_CHAR(DATE '2026-03-14', 'MM/DD/YYYY') donne '03/14/2026', et le modèle 'Mon DD, YYYY' donne 'Mar 14, 2026'. Oracle utilise aussi ces modèles. Le format américain dans SQLite est strftime('%m/%d/%Y', '2026-03-14').

Les lettres des modèles propres à chaque base de données ont leur signification. Dans PostgreSQL, MM signifie mois et MI minute. Dans SQLite, %m signifie mois et %M minute ; changer cette majuscule change l’information demandée.

SELECT TO_CHAR(order_date, 'MM/DD/YYYY') AS order_day
FROM orders
ORDER BY order_date;

Ici, PostgreSQL affiche du texte lisible mais trie les dates réelles. Trier order_day trierait les chaînes d’affichage d’abord par mois et pourrait placer dans le désordre des dates d’années différentes.

Points clés

  • EXTRACT dans PostgreSQL renvoie des composantes numériques ; strftime dans SQLite renvoie du texte.
  • Compare un mois SQLite précédé d’un zéro à du texte ou convertis-le en nombre.
  • La numérotation des jours de la semaine dépend de la convention demandée.
  • Conserve l’année dans les libellés de mois et ne mets en forme que pour l’affichage.

4.3 Calculer avec des dates et filtrer des plages de dates

Les calculs calendaires doivent tenir compte de la longueur des mois, des composantes horaires et du type de réponse recherché. Un nombre de jours, un mois calendaire et une année d’âge révolue sont des mesures différentes.

Ajouter des jours et des mois calendaires

PostgreSQL écrit DATE '2026-03-14' + 30 ; SQLite écrit date('2026-03-14', '+30 days'). Les deux atteignent le 13 avril : 17 jours terminent le mois de mars et 13 jours supplémentaires mènent au 13 avril. L’expression directe '2026-03-14' + 30 dans SQLite donne quant à elle 2056, car l’opération arithmétique lit l’année initiale comme un nombre.

Les fins de mois exigent une règle explicite. DATE '2026-01-31' + INTERVAL '1 month' dans PostgreSQL donne le 28 février à minuit, en utilisant le dernier jour disponible. date('2026-01-31', '+1 month') dans SQLite reporte les jours excédentaires sur mars et donne '2026-03-03'. À partir de SQLite 3.46, ajoute 'floor' après le décalage pour choisir '2026-02-28'. ADD_MONTHS dans Oracle passe aussi au dernier jour du mois plus court.

Mesurer le temps écoulé

Dans PostgreSQL, la soustraction de DATE renvoie des jours entiers : DATE '2026-04-13' - DATE '2026-03-14' vaut 30. SQLite soustrait des valeurs numériques de jours : julianday('2026-04-13') - julianday('2026-03-14') vaut 30.0. SQL Server utilise DATEDIFF(day, start, end) ; MySQL utilise DATEDIFF(end, start).

Pour des horodatages allant du 14 mars à 09 h 30 à 18 h 00, la soustraction dans PostgreSQL donne un intervalle de 08:30:00 ; EXTRACT(EPOCH FROM interval) / 3600 l’exprime sous la forme de 8,5 heures. À partir de SQLite 3.38, on peut écrire :

(unixepoch('2026-03-14 18:00') -
 unixepoch('2026-03-14 09:30')) / 3600.0

Cela donne 8.5. Une différence de jours juliens multipliée par 24 peut donner 8.49999999627471 à cause de l’approximation à virgule flottante ; arrondis pour l’affichage. Une durée fractionnaire entre horodatages ne doit pas être convertie en INTEGER avant que l’unité souhaitée ait été calculée.

Compter les anniversaires passés

Une personne née le 2 novembre 1990 a 35 ans le 21 octobre 2026. Les années diffèrent de 36, mais l’anniversaire n’est pas encore arrivé. PostgreSQL utilise EXTRACT(YEAR FROM AGE(DATE '2026-10-21', DATE '1990-11-02')), ce qui donne 35.

SQLite soustrait un si l’anniversaire de cette année n’est pas encore arrivé :

strftime('%Y', '2026-10-21') - strftime('%Y', birth_date)
- (strftime('%m-%d', '2026-10-21') < strftime('%m-%d', birth_date))

La comparaison donne 1 si l’anniversaire est encore à venir et 0 sinon. Diviser les jours écoulés par 365 n’est pas fiable : le 1er novembre 2026, cette personne a vécu 13 148 jours, ce qui, divisé par 365, donne 36,02 alors que son 36e anniversaire est demain. DATEDIFF dans SQL Server compte les frontières : passer du 31 décembre au 1er janvier compte comme une frontière d’année, et non comme une année d’âge révolue.

Inclure tous les horodatages d’une période

BETWEEN inclut les deux bornes. Pour les colonnes DATE, du 1er mars au 31 mars couvre le mois de mars. Pour les horodatages, une borne supérieure de '2026-03-31' signifie minuit au début du dernier jour et manque le reste de cette journée.

WHERE ordered_at >= '2026-03-01'
  AND ordered_at < '2026-04-01'

Cette plage semi-ouverte inclut le début et exclut le début de la période suivante, couvrant ainsi toutes les heures de mars sans choisir une dernière fraction de seconde.

Les dates échues satisfont due_date < CURRENT_DATE. La borne inférieure des 30 derniers jours est CURRENT_DATE - 30 dans PostgreSQL et date('now', '-30 days') dans SQLite. Le nombre de jours jusqu’à une échéance est donné par due_date - CURRENT_DATE pour les valeurs DATE dans PostgreSQL et par julianday(due_date) - julianday(date('now')) dans SQLite.

Points clés

  • Utilise des fonctions de calcul sur les dates ou des dates typées, plutôt que des opérations arithmétiques sur du texte de date dans SQLite.
  • Décide comment l’ajout d’un mois doit traiter un jour absent du mois suivant.
  • Les différences entre DATE comptent des jours ; celles entre horodatages peuvent inclure des fractions.
  • L’âge compte les anniversaires passés, pas les jours écoulés divisés par 365.
  • Une plage d’horodatages semi-ouverte inclut le début de la période et exclut le début de la suivante.
  • Utilise une valeur actuelle limitée à la date pour calculer les échéances en jours entiers.
5

Classer des lignes avec des expressions CASE

Un rapport a souvent besoin d’une règle qui transforme des données en libellé ou en frais : une petite commande, une expédition en attente ou un rang de priorité. CASE exprime ce choix dans une requête. Tu suivras la condition retenue, placeras les valeurs exactement aux bornes et les valeurs manquantes dans la bonne catégorie, et traduiras des codes avec le CASE simple. Le rapport final combine le classement avec des opérations arithmétiques, du texte, des dates et des valeurs de repli, en vérifiant chaque résultat sur des lignes connues.

5.1 Répartir des lignes en catégories avec un CASE recherché

Une expression CASE choisit un résultat pour chaque ligne. Tu peux l’utiliser pour attribuer un libellé à une tranche de prix, calculer des frais ou marquer un enregistrement qui mérite une attention particulière.

Lire la forme recherchée
CASE
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END AS size_band

Chaque WHEN fournit une condition et THEN fournit la valeur à renvoyer si cette condition vaut TRUE. La base de données vérifie les conditions de haut en bas et retient la première condition vraie. END ferme l’expression ; un alias peut le suivre. Si aucune condition ne vaut TRUE et que ELSE est absent, le résultat est NULL.

Un total de 35 remplit la première condition et devient 'small'. Un total de 50 ne remplit pas la première mais remplit la deuxième et devient 'medium'. Il en va de même pour 199,99. Un total de 200 atteint ELSE et devient 'large'.

Faire correspondre l’ordre et les bornes à la règle

La deuxième branche n’a pas besoin de total >= 50 : une valeur inférieure à 50 a déjà donné lieu à un résultat dans la première branche. Les seuils croissants avec < fonctionnent parce que les branches précédentes ont déjà traité les valeurs plus petites. Des seuils décroissants avec >= peuvent fonctionner pour la même raison.

Placer WHEN total < 200 en premier rend inaccessible une branche < 50 ultérieure. Un total de 35 satisfait déjà < 200, donc il s’arrête là. CASE ne choisit pas la condition la plus précise et ne vérifie pas quel libellé semble le mieux convenir.

Compare la règle métier à chaque borne. < 50 place exactement 50 dans la tranche moyenne ; <= 50 le place dans la petite tranche. Vérifie 49,99, 50, 199,99 et 200 pour examiner les deux côtés et les bornes. Si les conditions sont écrites sous forme d’intervalles explicites, fais correspondre leurs bornes sans laisser de vide ni de chevauchement involontaire.

Traiter NULL avant les plages ordinaires

Un total NULL rend les deux comparaisons UNKNOWN. Dans la première expression, il atteint donc ELSE et devient 'large', ce qui est trompeur. Détecte d’abord les valeurs manquantes :

CASE
  WHEN total IS NULL THEN 'unknown'
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END

ELSE signifie « aucune condition n’était vraie » : il peut donc prendre en compte les entrées manquantes aussi bien que les valeurs connues situées hors des plages testées.

Renvoyer un type de valeur cohérent

PostgreSQL exige des types compatibles pour THEN et ELSE. CASE WHEN quantity > 0 THEN unit_price ELSE 'n/a' END échoue si unit_price est numérique, car 'n/a' ne peut pas devenir un nombre. Utilise NULL pour un résultat numérique indisponible, ou convertis le prix en texte si toute la sortie est un libellé d’affichage. SQLite autorise des types de résultats mélangés, ce qui peut compliquer les calculs ultérieurs.

Une condition peut combiner des colonnes :

CASE
  WHEN country = 'US' AND subtotal >= 100 THEN 0
  ELSE 7.99
END AS shipping_fee

Les frais renvoyés peuvent figurer dans subtotal + CASE ... END AS amount_due. Un CASE est une expression qui produit une valeur, pas une commande qui modifie plusieurs colonnes ; chaque colonne de résultat a besoin de sa propre expression.

CASE peut aussi protéger une division effectuée sur chaque ligne : CASE WHEN visits = 0 THEN NULL ELSE orders * 100.0 / visits END. Une ligne dont la valeur est nulle sélectionne la branche NULL. orders * 100.0 / NULLIF(visits, 0) exprime la même règle de taux manquant plus brièvement.

Points clés

  • CASE renvoie la valeur associée à la première condition qui vaut TRUE.
  • Ordonne les conditions de plages qui se chevauchent pour qu’un test large ne masque pas un test plus restreint.
  • Choisis < ou <= pour placer une valeur exactement à la borne dans la tranche voulue.
  • Teste explicitement NULL avant une plage lorsque ELSE ne doit pas lui attribuer de libellé.
  • Garde des types de résultats compatibles et utilise CASE partout où une expression de valeur convient.

5.2 Utiliser le CASE simple et employer CASE dans toute une requête

La forme CASE simple traduit une valeur en une autre. Le CASE recherché teste des conditions ; le CASE simple compare la même expression à une série de valeurs.

Traduire des codes avec le CASE simple
CASE status
  WHEN 'S' THEN 'Shipped'
  WHEN 'P' THEN 'Pending'
  WHEN 'C' THEN 'Canceled'
  ELSE 'Other'
END AS status_label

Les tests implicites sont status = 'S', puis status = 'P', puis status = 'C'. Un statut hors de ces codes reçoit 'Other'. La forme recherchée peut écrire explicitement les mêmes tests d’égalité. Choisis le CASE recherché pour les plages, les motifs LIKE, les tests NULL ou les conditions portant sur plusieurs colonnes.

CASE region WHEN NULL THEN 'missing' ELSE region END ne peut pas détecter une région NULL. Son test implicite region = NULL vaut UNKNOWN, donc la ligne atteint ELSE et reste NULL. Écris CASE WHEN region IS NULL THEN 'missing' ELSE region END.

Attribuer un rang de tri personnalisé

L’ordre alphabétique des priorités est high, low, medium. Pour trier selon l’urgence, traduis les libellés en nombres :

SELECT ticket_id, priority
FROM tickets
ORDER BY CASE priority
           WHEN 'high' THEN 1
           WHEN 'medium' THEN 2
           WHEN 'low' THEN 3
           ELSE 4
         END;

L’ordre croissant place maintenant high avant medium, puis low, avec les autres valeurs ou les valeurs manquantes en dernier. Le CASE est une expression de tri ; il n’a pas besoin d’être une colonne affichée. Utiliser DESC inverserait le classement numérique.

Créer un indicateur numérique
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END AS is_discounted

Un pourcentage positif reçoit 1 ; un zéro connu reçoit 0. Un pourcentage NULL reçoit aussi 0 parce que > 0 vaut UNKNOWN et que ELSE le prend en compte. Cet indicateur signifie donc « une remise positive est enregistrée ». Il ne conserve pas la distinction entre l’absence de remise et une remise inconnue. Si cette distinction est nécessaire, ajoute une branche IS NULL avec son propre résultat.

Les indicateurs peuvent être sélectionnés, triés, filtrés ou inclus dans des opérations arithmétiques. Dans une clause WHERE portable, répète l’expression ou utilise sa condition d’origine au lieu de faire référence à un alias de sortie nouvellement défini.

Reconnaître les fonctions conditionnelles associées

COALESCE(bonus, 0) est une forme abrégée de CASE WHEN bonus IS NOT NULL THEN bonus ELSE 0 END. NULLIF(a, b) correspond à CASE WHEN a = b THEN NULL ELSE a END. Leurs noms communiquent directement ces usages courants.

SQLite à partir de la version 3.32 et SQL Server possèdent IIF(condition, true_value, false_value) ; MySQL possède IF. DECODE dans Oracle traduit les correspondances par égalité, par exemple DECODE(status, 'S', 'Shipped', 'P', 'Pending', 'Other'). DECODE considère deux NULL comme égaux, contrairement aux comparaisons d’égalité du CASE simple. Le CASE standard fonctionne dans ces systèmes.

Un CASE peut contenir un autre CASE, mais des conditions combinées rendent souvent une expression sans imbrication plus claire. Une règle d’expédition peut dire directement WHEN country = 'US' AND subtotal >= 100 THEN 0, en gardant ensemble les tests sur le pays et le sous-total.

Points clés

  • Le CASE simple compare une expression à des valeurs par égalité.
  • Utilise le CASE recherché pour les tests NULL, les plages et les conditions combinées.
  • Un CASE numérique dans ORDER BY crée un classement personnalisé.
  • Un indicateur avec ELSE 0 attribue aussi zéro lorsque sa condition vaut UNKNOWN.
  • COALESCE et NULLIF expriment des cas particuliers courants de CASE.
  • DECODE dans Oracle considère deux NULL comme égaux ; le CASE simple ne le fait pas.

5.3 Combiner des fonctions dans une requête de rapport complète

Un rapport peut nettoyer des noms, calculer des totaux nets, identifier des mois et attribuer un libellé à la rapidité d’expédition dans un seul SELECT. Construis chaque expression à partir de ses entrées et vérifie le résultat avant de la combiner aux autres.

Partir de lignes connues

Une table de commandes contient ces enregistrements. Les dates sont du texte ISO pour la requête SQLite ci-dessous ; quantity est un entier et unit_price est numérique.

CommandeClientQuantitéPrixRemise %CommandéeExpédiée
1001Ana Lopez312,50102026-03-142026-03-17
1002Ben Okafor1240,0002026-03-30NULL
1003Chen Wu124,25NULL2026-04-022026-04-03

Ici, une remise manquante signifie qu’il n’y a pas de remise. Commence par extraire les champs bruts. Ajoute une colonne calculée à la fois et utilise LIMIT 5 pour vérifier un petit échantillon.

Suivre un calcul imbriqué
ROUND(quantity * unit_price *
      (1 - COALESCE(discount_pct, 0) / 100.0), 2)

COALESCE fournit d’abord une remise connue. La division par 100.0 conserve sa partie fractionnaire. La soustraction à 1 donne la fraction payée, la multiplication donne le montant net et ROUND fixe la précision finale. Le montant d’Ana est 33.75, celui de Ben est 240.0 et celui de Chen est 51.0. La remise NULL de Chen devient zéro ; une date d’expédition manquante, en revanche, doit rester manquante dans le nombre de jours.

Assembler le rapport SQLite
SELECT order_id,
       first_name || ' ' || last_name AS customer,
       ROUND(quantity * unit_price *
         (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net_total,
       strftime('%Y-%m', order_date) AS order_month,
       CAST(julianday(shipped_date) - julianday(order_date)
         AS INTEGER) AS days_to_ship,
       CASE
         WHEN shipped_date IS NULL THEN 'not shipped'
         -- fast = shipped within 2 days
         WHEN julianday(shipped_date) - julianday(order_date) <= 2
           THEN 'fast'
         ELSE 'standard'
       END AS shipping
FROM orders
ORDER BY order_id;

Chaque expression possède un alias de sortie explicite. La différence numérique en jours est convertie en INTEGER car ces valeurs ne contiennent que des dates. La branche IS NULL vient avant la comparaison de rapidité, de sorte qu’une commande non expédiée reçoit un libellé utile.

Le résultat est :

CommandeClientTotal netMoisJoursExpédition
1001Ana Lopez33.752026-033standard
1002Ben Okafor240.02026-03NULLnot shipped
1003Chen Wu51.02026-041fast
Adapter les types et les clauses de la requête

Pour des colonnes DATE dans PostgreSQL, utilise TO_CHAR(order_date, 'YYYY-MM') pour le mois et shipped_date - order_date pour le nombre de jours et la comparaison dans CASE. Garde unit_price dans le type exact numeric pour ROUND à deux arguments. La concaténation, la valeur de repli pour la remise et la règle de classement gardent le même sens.

Pour filtrer les totaux arrondis supérieurs à 50 dans les deux bases, répète l’expression complète du montant net dans WHERE. Les commandes 1002 et 1003 restent. SQLite autorise aussi WHERE net_total > 50, mais PostgreSQL ne peut pas voir ce nouvel alias à l’étape du filtrage. ORDER BY net_total DESC fonctionne dans les deux.

Lorsque tu transfères un rapport, vérifie les types et les noms de fonctions dans chaque expression. Une fonction de texte doit recevoir du texte, un calcul de date doit recevoir une valeur de date prise en charge et une valeur de repli numérique doit exprimer la règle voulue. Place chaque résultat sur sa propre ligne ; un court commentaire peut définir un seuil métier sans rendre le SQL difficile à lire.

Points clés

  • Construis et vérifie une colonne calculée à la fois sur un petit échantillon.
  • Les fonctions imbriquées transmettent leurs résultats vers l’extérieur ; veille à ce que chaque entrée ait le type adapté.
  • Une remise manquante et une date d’expédition manquante peuvent nécessiter des traitements différents.
  • Utilise des expressions de date adaptées au dialecte tout en gardant des règles de rapport cohérentes.
  • Filtre avec l’expression complète et trie avec son alias de sortie lorsque c’est approprié.

Colonnes calculées SQL : exemples

5 Leçons Interactives

1

Calculer et vérifier le montant d’une ligne après remise

16 étapes
Calcule un montant, nomme-le, conserve sa partie fractionnaire et vérifie les types qui déterminent le résultat.
  1. 1
    IntroductionTransformer une ligne en montant utile

    Une ligne de commande enregistre huit articles à 7,50 chacun avec une remise de 20 pour cent. Le rapport a besoin d’un montant net, mais la table ne stocke que les données de départ. Tu construiras l’expression par étapes, nommeras sa sortie et vérifieras l’effet de la division entière sur la remise.

    Les exemples utilisent SQLite et PostgreSQL. Lorsque leurs règles de type diffèrent, le nom de la base de données précise à quel résultat il correspond.

  2. 2
    ExplicationCommencer par une expression

    Une expression combine des valeurs pour produire une autre valeur. Ici, quantity * unit_price utilise deux colonnes de la ligne courante.

    SELECT quantity * unit_price AS gross_total
    FROM order_lines;
    

    gross_total est l’alias de sortie. Pour la ligne de l’exemple, la nouvelle valeur est 60.0 dans SQLite. Chaque autre ligne fournit ses propres données ; la requête ne réécrit pas ces totaux dans la table.

  3. 3
    LienChaque ligne conserve sa propre valeur

    Une fonction monoligne renvoie une valeur pour chaque ligne d’entrée. ROUND(unit_price, 0) modifie le prix affiché pour une ligne, tandis que UPPER(item_name) modifie le texte affiché.

    Ces fonctions ne combinent pas les lignes de commande. Un agrégat comme SUM combine les valeurs d’un groupe et répond donc à un autre type de question. Un calcul dans SELECT peut conserver le détail des commandes individuelles.

  4. 4
    ConseilNommer clairement le résultat

    AS net_total est un alias simple et lisible. Utilise des guillemets doubles lorsqu’un nom contient un espace, comme dans AS "Net Total". Les apostrophes désignent quant à elles les valeurs textuelles.

    Garde une virgule entre les expressions de sortie. SELECT quantity unit_price renvoie une colonne de quantités sous l’en-tête unit_price : sans virgule, le deuxième nom devient un alias. Cette requête peut réussir tout en affichant moins de colonnes que prévu.

  5. 5
    DéfiPlacer l’alias dans la requête

    La table ne contient que quantity et unit_price. Une requête définit quantity * unit_price AS gross_total. Un filtre WHERE dans PostgreSQL peut-il utiliser gross_total > 50, et ORDER BY peut-il utiliser gross_total DESC ?

    ---reveal---

    WHERE ne peut pas voir ce nouvel alias parce qu’il précède logiquement SELECT. Répète quantity * unit_price > 50. ORDER BY suit SELECT et peut utiliser gross_total DESC. SQLite autorise l’alias dans WHERE comme extension, mais pas PostgreSQL.

  6. 6
    ExempleTransformer une remise en fraction payée

    Le montant brut est 8 * 7.50, soit 60. Une remise de 20 pour cent laisse 80 pour cent à payer. Exprime cela par 1 - discount_pct / 100.0.

    quantity * unit_price * (1 - discount_pct / 100.0)
    

    La division donne 0.2 ; les parenthèses donnent 0.8 ; la multiplication donne un montant net de 48.0. Les parenthèses maintiennent la soustraction comme un seul facteur multiplicatif.

  7. 7
    Point cléUn décimal ultérieur ne peut pas corriger une division antérieure

    Supposons que discount_pct soit un entier et que le diviseur soit écrit 100. SQLite et PostgreSQL calculent 20 / 100 comme une division entière et obtiennent 0. Le facteur devient 1, donc le montant net reste à tort égal à 60.

    Le prix décimal ailleurs dans l’expression ne corrige pas cette division intérieure. Utilise 100.0 dans la division elle-même. Convertir le quotient une fois calculé change son type mais ne peut pas restaurer la fraction perdue.

  8. 8
    DéfiTrouver le calcul qui a perdu sa fraction

    Une ligne SQLite contient les entiers completed = 9 et assigned = 12. Que renvoie completed / assigned * 100.0, et comment l’expression devrait-elle calculer le pourcentage ?

    ---reveal---

    Elle renvoie 0.0 : la division entière 9 / 12 devient d’abord 0. Écris completed * 100.0 / assigned, ce qui donne 75.0. La conversion doit avoir lieu avant la division, et pas seulement avant l’affichage final.

  9. 9
    ExplicationChoisir la règle pour obtenir un entier

    ROUND choisit une valeur arrondie proche. FLOOR descend jusqu’à un entier, CEIL monte et TRUNC supprime la partie fractionnaire par troncation vers zéro.

    Pour -6.4, FLOOR donne -7, tandis que CEIL et TRUNC donnent -6. Le sens compte pour les entrées négatives. PostgreSQL fournit ces fonctions ; dans SQLite, CEIL, FLOOR et TRUNC exigent une version compilée avec les fonctions mathématiques. ABS, qui donne la distance à zéro, est intégré à SQLite.

  10. 10
    ConseilVérifier le type numérique avant d’arrondir

    Dans PostgreSQL, ROUND à deux arguments prend numeric, pas double precision. Pour une colonne à virgule flottante, écris ROUND(CAST(amount AS numeric), 2). SQLite accepte sa propre forme numérique de ROUND.

    Les valeurs approximatives à virgule flottante peuvent produire des cas d’arrondi à mi-chemin surprenants. Pour les montants exacts, NUMERIC/DECIMAL dans PostgreSQL stocke des décimaux exacts ; SQLite peut conserver des centimes entiers comme entiers. Arrondis le résultat affiché après le calcul.

  11. 11
    ExplicationRendre explicite un changement de type

    CAST(expression AS type) demande une conversion. Le texte '28' peut devenir l’entier 28 avec CAST('28' AS INTEGER). Le nombre peut devenir du texte avec CAST(28 AS TEXT).

    Pour une division avec résultat fractionnaire, SQLite exige REAL afin d’obtenir un opérande non entier de façon fiable. CAST(7 AS NUMERIC) peut encore y être l’entier 7. NUMERIC dans PostgreSQL fournit un type décimal exact. Une conversion CAST de NULL reste NULL.

  12. 12
    ExempleDistinguer les identifiants des quantités

    Supposons qu’un libellé stocke le code postal américain '00421'. Le convertir en entier donne 421, ce qui fait perdre les zéros initiaux. C’est un identifiant : il ne s’agit donc pas de faire des calculs avec lui.

    Une colonne de texte qui contient réellement des quantités peut nécessiter une conversion pour un tri numérique. Les textes '12', '3' et '80' sont triés dans cet ordre ; le tri numérique donne 3, 12, 80. Choisis la conversion selon le sens de la colonne.

  13. 13
    DéfiInterpréter une conversion sans la prendre pour une validation

    SQLite exécute CAST('31units' AS INTEGER) sans erreur. Quelle valeur renvoie-t-il, et cette réussite montre-t-elle que le texte d’origine était un entier valide ?

    ---reveal---

    Il renvoie 31 en lisant la partie numérique initiale. La réussite ne valide pas toute la chaîne. PostgreSQL rejette le même texte comme entier. SQLite peut aussi transformer en zéro un texte sans préfixe numérique, masquant ainsi une entrée incorrecte.

  14. 14
    Point cléUne conversion en entier ne fonctionne pas partout de la même façon

    Pour la valeur numérique 4.7, CAST(... AS INTEGER) dans SQLite tronque à 4, tandis que PostgreSQL arrondit à 5. Si un rapport demande « les unités entières ne dépassant pas cette valeur », exprime cette règle avec FLOOR avant la conversion.

    Une conversion implicite dépend aussi de la base de données. PostgreSQL peut déduire un nombre à partir d’un littéral entre apostrophes dans une opération arithmétique, mais une colonne TEXT exige une conversion explicite. Les seuls caractères visibles ne déterminent pas le type de l’opérande.

  15. 15
    DéfiVérifier l’expression complète du montant net

    Pour huit articles à 7,50 avec l’entier discount_pct = 20, un rapport utilise ROUND(quantity * unit_price * (1 - discount_pct / 100.0), 2) AS net_total. Quel est le résultat, et cet alias peut-il servir à trier la sortie ?

    ---reveal---

    Le montant brut est 60, la fraction payée est 0,8 et le montant net est 48.0 dans SQLite. ORDER BY net_total est valide dans SQLite et PostgreSQL, car le tri peut voir l’alias SELECT.

  16. 16
    RécapitulatifLire les données d’entrée, le calcul et le nom de sortie

    Un montant calculé suit un parcours : la ligne fournit les valeurs, les opérations arithmétiques et les fonctions produisent le résultat, et un alias le nomme. Vérifie l’ordre des opérations et les types des opérandes avant d’accepter un nombre affiché.

    Lorsqu’un résultat est inattendu, examine d’abord une division ou une conversion intérieure. Pour filtrer une valeur calculée dans différentes bases de données, répète son expression dans WHERE ; pour la trier, utilise l’alias de sortie dans ORDER BY.

2

Suivre les données manquantes dans une requête

12 étapes
Suis les conditions UNKNOWN, puis choisis et combine COALESCE et NULLIF.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionUn montant manquant affecte plus qu’une cellule
  2. 2
    ExplicationNULL est une entrée inconnue
  3. 3
    ExempleUtiliser un test qui détecte les valeurs manquantes
  4. 4
    Point cléWHERE n’accepte que TRUE
  5. 5
    DéfiCombiner une condition connue et une condition inconnue
  6. 6
    ConseilNe pas laisser NULL dans une liste d’exclusion
  7. 7
    ExplicationChoisir une valeur de repli selon le sens
  8. 8
    ExempleGarder un type d’affichage cohérent
  9. 9
    ExempleTransformer un dénominateur nul en valeur manquante
  10. 10
    DéfiNettoyer la chaîne vide avant d’attribuer le libellé
  11. 11
    DéfiDistinguer le choix d’affichage du choix de filtrage
  12. 12
    RécapitulatifGarder visible le sens d’une valeur manquante
3

Nettoyer un nom et extraire un domaine d’adresse e-mail

14 étapes
Concatène du texte, imbrique des fonctions de nettoyage et suis les positions des caractères autour d’un séparateur.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionRendre le texte utilisable sans perdre ses parties
  2. 2
    ExempleFournir l’espace entre les noms
  3. 3
    ExplicationDécider de l’effet d’une partie de nom manquante
  4. 4
    ExempleNettoyer l’adresse e-mail de l’intérieur vers l’extérieur
  5. 5
    DéfiChoisir entre suppression aux extrémités et remplacement
  6. 6
    ConseilVérifier les règles relatives aux caractères et au dialecte
  7. 7
    ExplicationCompter à partir de un
  8. 8
    ExempleRepérer le séparateur
  9. 9
    ExemplePrendre les caractères avant et après @
  10. 10
    DéfiTrouver le résultat décalé d’une position
  11. 11
    Point cléUn résultat de recherche nul demande un traitement particulier
  12. 12
    ConseilExtraire les fins et remplir les codes dans le bon dialecte
  13. 13
    DéfiCombiner nettoyage et extraction
  14. 14
    RécapitulatifSuivre les caractères exacts
4

Créer des libellés de date et des filtres de période fiables

18 étapes
Lis des valeurs de date, mets-les en forme pour l’affichage et calcule des échéances, des durées et des périodes complètes.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionDistinguer la date calendaire de son libellé
  2. 2
    ExplicationChoisir une représentation claire de la date
  3. 3
    ExempleLire un format local fixe
  4. 4
    DéfiExpliquer quel texte se trie dans l’ordre des dates
  5. 5
    ConseilVérifier l’analyse et la référence temporelle actuelle
  6. 6
    ExempleExtraire le mois avec le bon type de retour
  7. 7
    ExplicationConserver l’année dans le libellé de mois
  8. 8
    ExempleCréer un affichage sans modifier le tri
  9. 9
    DéfiTrouver le bon trimestre
  10. 10
    LienChoisir la convention de numérotation des jours de la semaine
  11. 11
    ExempleAjouter dix jours à la réservation
  12. 12
    Point cléUn mois n’est pas un nombre fixe de jours
  13. 13
    ExempleMesurer les jours et les heures dans les unités adaptées
  14. 14
    DéfiInclure le dernier après-midi du mois
  15. 15
    ExplicationCompter les anniversaires effectivement passés
  16. 16
    ConseilLire les dates relatives comme des bornes mobiles
  17. 17
    DéfiCombiner une échéance et une sélection par mois
  18. 18
    RécapitulatifVérifier le type, la règle calendaire et les bornes
5

Attribuer des libellés aux commandes et construire le rapport final

17 étapes
Choisis les branches CASE, traduis les priorités et combine plusieurs résultats calculés.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionDonner un libellé utile à chaque commande
  2. 2
    ExplicationChoisir la première condition vraie
  3. 3
    ExempleSuivre le seuil exact
  4. 4
    Point cléELSE peut aussi prendre en compte un montant inconnu
  5. 5
    DéfiCorriger une tranche de petits montants masquée
  6. 6
    ConseilRenvoyer des résultats compatibles
  7. 7
    ExempleTraduire une valeur de statut
  8. 8
    DéfiPourquoi WHEN NULL ne détecte-t-il pas la ligne ?
  9. 9
    ExempleTrier les priorités par rang
  10. 10
    Point cléUn indicateur peut réunir des cas connus et inconnus
  11. 11
    ExempleCommencer le rapport avec des données connues
  12. 12
    ExempleCalculer d’abord le montant net
  13. 13
    ExempleAjouter les dates avec une règle distincte pour les valeurs manquantes
  14. 14
    DéfiVérifier une deuxième ligne selon les deux règles
  15. 15
    LienTransposer les expressions de date dans PostgreSQL
  16. 16
    DéfiFiltrer le montant réellement affiché par le rapport
  17. 17
    RécapitulatifVérifier le rapport comme un ensemble de choix explicites

Colonnes calculées SQL : QCM

40 Questions Pratiques en 4 séries

Série 1 : Calculer des montants et gérer les données manquantes10 Questions Pratiques

Question 1 sur 10

Une table PostgreSQL ne contient que units et unit_cost. Quelle liste SELECT renvoie leur produit sous l’en-tête extended_cost ?
  1. units + unit_cost AS extended_cost
  2. units * unit_cost AS extended_cost
  3. units * unit_cost, extended_cost
  4. units * 'unit_cost' AS extended_cost
Afficher la réponseMasquer la réponse
Réponse : B
units * unit_cost multiplie les valeurs de chaque ligne et AS extended_cost nomme cette sortie. Ajouter une virgule avant le nom demande une colonne distincte, que cette table ne possède pas. Les apostrophes feraient de unit_cost un littéral textuel au lieu d’une référence à la colonne de coût.

Question 2 sur 10

La table lines ne contient que units et price. Une requête doit fonctionner dans SQLite et PostgreSQL. Comment doit-elle conserver les lignes dont le produit est supérieur à 90 et trier le produit le plus élevé en premier ?
  1. SELECT units * price AS amount FROM lines WHERE amount > 90 ORDER BY amount DESC;
  2. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount ASC;
  3. SELECT units * price AS amount FROM lines ORDER BY amount DESC WHERE units * price > 90;
  4. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount DESC;
Afficher la réponseMasquer la réponse
Réponse : D
Répète units * price dans WHERE, car PostgreSQL ne peut pas utiliser un nouvel alias SELECT à cette étape. ORDER BY vient logiquement après SELECT et peut donc trier selon l’alias avec DESC. SQLite peut accepter l’alias dans WHERE, mais cette version ne satisferait pas l’exigence de fonctionner dans les deux bases.

Question 3 sur 10

Que renvoie SELECT 14 + 5 * 3; dans SQLite ?
  1. 29
  2. 57
  3. 33
  4. 75
Afficher la réponseMasquer la réponse
Réponse : A
La multiplication a lieu avant l’addition : SQL calcule donc d’abord 5 * 3, soit 15, puis ajoute 14 pour obtenir 29. Le résultat 57 provient de l’addition préalable de 14 et 5. Cet ordre exigerait des parenthèses autour de 14 + 5 ; l’expression présentée n’en comporte pas.

Question 4 sur 10

Dans SQLite, old_count et new_count sont des entiers qui contiennent 60 et 69. Quel est le résultat de (new_count - old_count) / old_count * 100 ?
  1. 15
  2. 0.15
  3. 0
  4. 9
Afficher la réponseMasquer la réponse
Réponse : C
La soustraction donne l’entier 9, et 9 / 60 est une division entière qui produit 0 avant la multiplication par 100. Le pourcentage recherché est 15, mais l’expression perd d’abord sa partie fractionnaire. Écrire (new_count - old_count) * 100.0 / old_count permet de conserver le calcul décimal nécessaire.

Question 5 sur 10

Une ligne de facture SQLite contient les entiers units = 5 et discount_pct = 12, ainsi que price = 18.0. Quel résultat produit ROUND(units * price * (1 - discount_pct / 100), 2) ?
  1. 79.2
  2. 90.0
  3. 89.88
  4. 78.0
Afficher la réponseMasquer la réponse
Réponse : B
La division intérieure 12 / 100 utilise deux entiers : SQLite la tronque donc à 0. Le facteur devient 1 et ROUND reçoit le montant total, 5 * 18.0, ce qui donne 90.0. Le montant après remise de 79,2 exige un opérande décimal dans cette division ; un arrondi ultérieur ne peut pas restaurer la fraction perdue.

Question 6 sur 10

Que renvoie SQLite pour CAST('27boxes' AS INTEGER) ?
  1. 27
  2. 0
  3. Une erreur d’entier invalide
  4. NULL
Afficher la réponseMasquer la réponse
Réponse : A
SQLite convertit la plus longue partie initiale qui ressemble à un entier : les chiffres initiaux produisent donc 27. Il ne renvoie 0 que lorsqu’il n’existe aucun préfixe numérique utilisable. Pour ce texte, PostgreSQL produit une erreur d’entier invalide : la même conversion donne donc un résultat différent lorsqu’elle passe d’un système à l’autre.

Question 7 sur 10

Quelle condition trouve les lignes sans delivery_date enregistrée ?
  1. delivery_date = NULL
  2. delivery_date <> NULL
  3. delivery_date = ''
  4. delivery_date IS NULL
Afficher la réponseMasquer la réponse
Réponse : D
IS NULL teste directement si une valeur est manquante et renvoie une réponse certaine : TRUE ou FALSE. L’égalité avec NULL produit UNKNOWN même pour une date de livraison manquante, donc WHERE ne conserverait aucune de ces lignes. Une chaîne vide est une chaîne enregistrée dans SQLite et PostgreSQL, pas le marqueur d’une date inconnue.

Question 8 sur 10

Une table contient exactement quatre valeurs region : 'East', 'West', NULL et 'North'. Combien de lignes satisfont WHERE NOT (region = 'East') ?
  1. 3
  2. 2
  3. 1
  4. 4
Afficher la réponseMasquer la réponse
Réponse : B
Les comparaisons pour West et North valent FALSE : NOT rend donc ces conditions TRUE et conserve deux lignes. La comparaison avec NULL vaut UNKNOWN et sa négation reste UNKNOWN : cette ligne est donc exclue. Compter toutes les lignes sauf East reviendrait à traiter à tort une région manquante comme une région connue différente.

Question 9 sur 10

Dans SQLite, une chaîne de téléphone vide et NULL doivent tous deux s’afficher sous la forme 'unlisted'. Quelle expression permet cela tout en conservant les numéros enregistrés ?
  1. NULLIF(COALESCE(phone, ''), 'unlisted')
  2. COALESCE(phone, '', 'unlisted')
  3. COALESCE(NULLIF(phone, ''), 'unlisted')
  4. COALESCE(NULLIF(phone, 'unlisted'), '')
Afficher la réponseMasquer la réponse
Réponse : C
Le NULLIF intérieur transforme une chaîne de téléphone vide en NULL, puis COALESCE fournit le libellé d’affichage pour les deux types de valeur manquante. Un numéro non vide traverse les deux appels sans modification. COALESCE(phone, '', 'unlisted') laisse la chaîne vide intacte et la sélectionne même comme valeur de repli avant d’atteindre le libellé.

Question 10 sur 10

Un rapport PostgreSQL contient les entiers sales et visits. Un taux doit conserver les pourcentages fractionnaires et rester NULL lorsque visits vaut zéro. Il ne doit pas inventer un taux nul. Quelle expression convient ?
  1. COALESCE(sales * 100.0 / NULLIF(visits, 0), 0)
  2. sales / NULLIF(visits, 0) * 100.0
  3. sales * 100.0 / COALESCE(visits, 1)
  4. sales * 100.0 / NULLIF(visits, 0)
Afficher la réponseMasquer la réponse
Réponse : D
La multiplication par 100,0 rend le taux décimal avant la division, et NULLIF transforme un diviseur nul en NULL. Le résultat reste alors manquant pour zéro visite. Diviser d’abord les nombres entiers peut effacer une partie fractionnaire réelle du taux, tandis qu’un COALESCE extérieur vers zéro attribuerait à tort une valeur numérique à un taux indéfini.
Série 2 : Nettoyer du texte et manipuler des valeurs calendaires10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Que renvoie LOWER(TRIM(' RAE@Mail.COM ')) dans SQLite ?
  1. ' rae@mail.com '
  2. 'RAE@Mail.COM' (casse conservée)
  3. 'rae@mail.com'
  4. 'rae@mail.com '
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Une ligne SQLite 3.44 ou ultérieure contient first_name = 'Mira', middle_name = NULL et last_name = 'Shah'. Que renvoient first_name || ' ' || middle_name || ' ' || last_name et CONCAT_WS(' ', first_name, middle_name, last_name), dans cet ordre ?
  1. NULL ; 'Mira Shah'
  2. 'Mira Shah' ; 'Mira Shah'
  3. NULL ; NULL
  4. 'Mira Shah' ; 'Mira Shah'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Dans SQLite, que renvoie SUBSTR('Seattle', 3, 3) ?
  1. 'attl'
  2. 'tle'
  3. 'eat'
  4. 'att'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Dans PostgreSQL, une colonne TEXT email peut contenir NULL ou du texte sans @. Pour un texte contenant @, renvoie tout ce qui suit son premier @ ; sinon, renvoie NULL. Quelle expression convient ?
  1. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@')) END
  2. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  3. CASE WHEN STRPOS(email, '@') >= 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  4. CASE WHEN email IS NOT NULL THEN SUBSTR(email, STRPOS(email, '@') + 1) END
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Quel texte de date ISO représente le 6 novembre 2027 ?
  1. '2027-11-06'
  2. '11/06/2027'
  3. '2027-06-11'
  4. '2027-11-6'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Que renvoie SQLite dans sa version actuelle pour date('2027-04-31') ?
  1. '2027-04-30'
  2. Une erreur de date invalide
  3. '2027-05-01'
  4. NULL
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Dans SQLite, d contient '2027-08-19'. Quels sont les résultats de strftime('%m', d) = 8 et de CAST(strftime('%m', d) AS INTEGER) = 8, dans cet ordre ?
  1. TRUE ; TRUE
  2. FALSE ; TRUE
  3. FALSE ; FALSE
  4. TRUE ; FALSE
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Une colonne DATE PostgreSQL event_date couvre plusieurs années. Un rapport affiche les dates au format MM/JJ/AAAA et doit conserver l’ordre chronologique. Comment doit-il sélectionner et trier la colonne ?
  1. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY day_label;
  2. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY EXTRACT(MONTH FROM event_date), EXTRACT(DAY FROM event_date);
  3. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY CAST(TO_CHAR(event_date, 'MM/DD/YYYY') AS TEXT);
  4. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY event_date;
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Une date SQLite d vaut '2027-04-24'. Que renvoie date(d, '+10 days') ?
  1. '2027-05-03'
  2. '2027-04-34'
  3. '2027-05-04'
  4. '2027-05-05'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Une colonne TIMESTAMP PostgreSQL n’a pas de fuseau horaire et enregistre des heures tout au long de juin 2027. Quel filtre inclut toutes les valeurs de juin et aucune valeur de juillet ?
  1. logged_at >= '2027-06-01' AND logged_at < '2027-07-01'
  2. logged_at BETWEEN '2027-06-01' AND '2027-06-30'
  3. logged_at >= '2027-06-01' AND logged_at <= '2027-07-01'
  4. logged_at > '2027-06-01' AND logged_at < '2027-07-01'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 3 : Classer des lignes et diagnostiquer la logique d’un rapport10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Quel libellé ce CASE produit-il pour score = 75 : CASE WHEN score < 60 THEN 'review' WHEN score < 80 THEN 'ready' ELSE 'strong' END ?
  1. 'review'
  2. 'strong'
  3. NULL
  4. 'ready'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Pourquoi CASE WHEN amount < 500 THEN 'regular' WHEN amount < 100 THEN 'small' ELSE 'large' END ne renvoie-t-il jamais 'small' pour les montants qui ne sont pas NULL ?
  1. CASE vérifie d’abord la dernière plage correspondante.
  2. Tout montant inférieur à 100 satisfait déjà le test précédent inférieur à 500.
  3. La branche ELSE prend le pas sur une plage correspondante ultérieure.
  4. La deuxième condition n’est testée que pour les montants égaux à 500.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Une valeur numérique balance peut être NULL. Les libellés requis sont 'unknown' si elle est manquante, 'credit' en dessous de 0, 'settled' à 0 et 'due' au-dessus de 0. Quel CASE respecte toutes ces règles ?
  1. CASE WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  2. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance <= 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  3. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  4. CASE balance WHEN NULL THEN 'unknown' WHEN 0 THEN 'settled' ELSE 'due' END
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Pour state, la valeur 'H' signifie « retenu » et 'R' signifie « libéré ». Que renvoie CASE state WHEN 'H' THEN 'held' WHEN 'R' THEN 'released' ELSE 'other' END pour 'R' ?
  1. 'released'
  2. 'held'
  3. 'other'
  4. NULL
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Un rapport doit trier 'urgent', 'normal' et 'deferred' dans cet ordre, avec toutes les autres priorités et les priorités NULL en dernier. Quelle expression ORDER BY convient ?
  1. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END DESC
  2. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END DESC
  3. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 3 WHEN 'deferred' THEN 2 ELSE 4 END ASC
  4. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END ASC
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Une ligne SQLite contient qty = 4, price = 15.0, discount_pct = NULL et shipped_date = NULL. Une remise manquante signifie qu’il n’y en a pas. Quel couple est produit par ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) et CASE WHEN shipped_date IS NULL THEN 'open' ELSE 'sent' END ?
  1. NULL ; 'open'
  2. 0.0 ; 'open'
  3. 60.0 ; 'open'
  4. 60.0 ; 'sent'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un rapport SQLite affiche LOWER(TRIM(customer)) AS name et date(due_date, '+7 days') AS reminder_date. La valeur brute de customer est ' IVAN ' et due_date vaut '2027-09-26'. Quel couple de sortie une vérification par échantillon doit-elle trouver ?
  1. 'ivan' ; '2027-10-03'
  2. ' ivan ' ; '2027-10-03'
  3. 'ivan' ; '2027-10-02'
  4. 'IVAN' (casse conservée) ; '2027-10-03'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Une table PostgreSQL contient les valeurs x 2, 7, NULL et 11. Quels sont les nombres de lignes pour WHERE x NOT IN (2, NULL) et WHERE x <> 2 OR x IS NULL, respectivement ?
  1. 2 et 3
  2. 0 et 3
  3. 0 et 2
  4. 3 et 3
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Une personne est née le '1998-12-18'. Au '2027-12-17', quel est son âge révolu et pourquoi la soustraction des deux années peut-elle être erronée ?
  1. 28 ans ; l’anniversaire n’a pas encore eu lieu en 2027.
  2. 29 ans ; une nouvelle année civile complète une année d’âge.
  3. 28 ans ; les personnes nées en décembre comptent toujours une année de moins.
  4. 29 ans ; les jours écoulés divisés par 365 donnent l’âge.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Une colonne INTEGER PostgreSQL rating peut être NULL. Une colonne d’affichage doit montrer la note sous forme de texte ou afficher 'unrated'. Quelle expression convient ?
  1. CAST(COALESCE(rating, 'unrated') AS TEXT)
  2. NULLIF(CAST(rating AS TEXT), 'unrated')
  3. COALESCE(CAST(rating AS TEXT), 'unrated')
  4. CAST(NULLIF(rating, 0) AS TEXT)
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 4 : Vérifier des rapports complets et des valeurs limites délicates10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Une table PostgreSQL ne contient que l’entier qty, la valeur NUMERIC price et l’entier discount_pct. Une remise manquante signifie qu’il n’y en a pas. Un rapport doit conserver les totaux nets arrondis supérieurs à 75 et les trier du plus élevé au plus faible. Quelle requête complète convient ?
  1. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE net > 75 ORDER BY net DESC;
  2. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net DESC;
  3. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) > 75 ORDER BY net DESC;
  4. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net ASC;
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Une colonne PostgreSQL reading est de type DOUBLE PRECISION. Comment un rapport peut-il l’arrondir à deux décimales sans erreur de signature de fonction ?
  1. ROUND(reading, 2)
  2. CAST(ROUND(reading) AS NUMERIC)
  3. ROUND(CAST(reading AS NUMERIC), 2)
  4. ROUND(CAST(reading AS INTEGER), 2)
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Que renvoie COALESCE(NULL, '', 'backup') dans SQLite ?
  1. ''
  2. 'backup'
  3. NULL
  4. 'NULL'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Dans SQLite, une ligne contient email = 'nora@research.org'. Quel résultat produit SUBSTR(email, INSTR(email, '@')) ?
  1. 'research.org'
  2. 'nora'
  3. 'nora@'
  4. '@research.org'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Pour '2027-01-31', compare date(d, '+1 month') dans SQLite 3.46 ou ultérieur, date(d, '+1 month', 'floor') dans SQLite et DATE '2027-01-31' + INTERVAL '1 month' dans PostgreSQL. Quelles dates calendaires obtient-on, dans cet ordre ?
  1. 28 février ; 28 février ; 28 février
  2. 3 mars ; 3 mars ; 28 février
  3. 3 mars ; 28 février ; 28 février
  4. 28 février ; 3 mars ; 3 mars
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Une valeur INTEGER PostgreSQL stock peut être NULL. L’indicateur numérique requis est NULL pour un stock inconnu, 1 pour un stock inférieur à 5 et 0 sinon. Quelle expression convient ?
  1. CASE WHEN stock < 5 THEN 1 ELSE 0 END
  2. CASE WHEN stock IS NULL THEN NULL WHEN stock < 5 THEN 1 ELSE 0 END
  3. CASE WHEN stock IS NULL THEN NULL WHEN stock <= 5 THEN 1 ELSE 0 END
  4. CASE stock WHEN NULL THEN NULL WHEN 5 THEN 0 ELSE 1 END
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

SQLite 3.38 ou ultérieur enregistre une session de '2027-05-08 10:15:00' à '2027-05-08 13:45:00'. Que renvoie (unixepoch(end_time) - unixepoch(start_time)) / 3600.0 ?
  1. 3.0
  2. 210.0
  3. 12600.0
  4. 3.5
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Une commande SQLite contient l’entier qty = 6, price = 8.0, discount_pct = 25, a été passée le '2027-07-10' et expédiée le '2027-07-12'. Le montant net utilise ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2). Un CASE attribue 'open' à une expédition NULL, 'fast' si le nombre de jours écoulés est <= 2, et 'standard' sinon. Quels montant net et libellé obtient-on ?
  1. 36.0 ; 'fast'
  2. 48.0 ; 'fast'
  3. 36.0 ; 'standard'
  4. 12.0 ; 'fast'
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Un rapport SQLite a besoin des numéros de trimestre de 1 à 4 pour toute date valide d. Comment peut-il calculer le trimestre pour chaque mois ?
  1. CAST(strftime('%m', d) AS INTEGER) / 3 + 1
  2. (CAST(strftime('%m', d) AS INTEGER) + 1) / 3
  3. ROUND(CAST(strftime('%m', d) AS INTEGER) / 3.0)
  4. (CAST(strftime('%m', d) AS INTEGER) + 2) / 3
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Une table SQLite contient les lignes A (qty 3, price 22.0, discount_pct NULL), B (qty 4, price 20.0, discount_pct 25) et C (qty 2, price 40.0, discount_pct 10). Une remise manquante signifie qu’il n’y en a pas. Elle calcule ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net, conserve net > 60 avec l’expression complète dans WHERE et trie par net DESC. Quel est l’ordre des lignes ?
  1. B, C, A
  2. C, A
  3. C, A, B
  4. A, C
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Tu bloques sur ton propre exercice ? Aide aux Devoirs

Mots-Clés

61 Mots-Clés, chacun avec sa définition

A

Affinité de type
L’affinité de type est la préférence de SQLite pour la façon dont une colonne stocke les valeurs ; une colonne ordinaire peut néanmoins contenir des valeurs de types différents.
Une déclaration NUMERIC dans SQLite peut conserver 7 comme entier : elle ne garantit donc pas une division décimale.
Alias de colonne
Un alias de colonne est un nom attribué à une colonne de sortie d’une requête, souvent avec AS, afin que le résultat ait un en-tête explicite.
La requête nomme son montant calculé avec AS line_total et peut le trier avec ORDER BY line_total.

Â

Âge révolu
L’âge révolu compte les anniversaires passés à une date de référence : il peut donc être nécessaire de soustraire une année à la différence entre les années.
Une personne née le 2 novembre 1990 a encore 35 ans le 21 octobre 2026, avant l’anniversaire de cette année-là.

B

Branche WHEN
Une branche WHEN est un choix condition-résultat dans CASE, où THEN fournit la valeur sélectionnée si cette condition est la première à être vraie.
Placer en premier une branche large < 200 peut empêcher qu’une branche ultérieure < 50 soit sélectionnée.

C

CASE recherché
Un CASE recherché teste les conditions dans leur ordre d’écriture et renvoie, pour la ligne courante, le résultat de la première condition TRUE.
CASE WHEN total < 50 THEN 'small' ELSE 'large' END choisit un libellé à partir du montant de la ligne.
CASE simple
Un CASE simple compare une expression à une suite de valeurs par égalité et renvoie le résultat associé à la première valeur correspondante.
CASE status WHEN 'S' THEN 'Shipped' ELSE 'Other' END traduit un code de statut stocké.
CEIL
CEIL est une fonction numérique qui renvoie le plus petit entier supérieur ou égal à son entrée ; CEILING est un autre nom de la fonction.
Le calcul CEIL(4.1) donne 5 car quatre est inférieur à l’entrée et cinq est l’entier suivant.
Chaîne de caractères
Une chaîne de caractères est une valeur textuelle composée de caractères, notamment des lettres, des chiffres, des signes de ponctuation et des espaces. En SQL, son littéral s’écrit entre apostrophes.
La chaîne ' New York ' contient des espaces aux extrémités et deux espaces intérieurs qui influent sur sa longueur.
Chaîne numérique
Une chaîne numérique est une chaîne contenant des caractères numériques ; sa forme textuelle influe sur le tri jusqu’à sa conversion pour un usage numérique.
Les chaînes '10', '100' et '9' apparaissent dans cet ordre croissant en tant que textes, ce qui diffère de l’ordre numérique.
Changement de casse
Le changement de casse met les lettres en majuscules ou en minuscules avec des fonctions comme UPPER et LOWER, selon les règles de caractères de la base de données.
LOWER(TRIM(email)) rend une adresse e-mail ASCII nettoyée cohérente pour une comparaison après uniformisation de la casse.
COALESCE
COALESCE est une fonction SQL standard qui renvoie le premier argument qui n’est pas NULL, ou NULL lorsque tous ses arguments sont NULL.
COALESCE(mobile_phone, home_phone, 'no phone') utilise le numéro fixe si le numéro de portable est manquant.
Collation
Une collation fournit des règles de comparaison et de classement du texte, notamment pour déterminer si des lettres de casse différente sont considérées comme égales.
La collation par défaut de MySQL, qui ignore la casse, peut rendre 'Boston' = 'boston' vrai alors que ce n’est pas le cas dans SQLite par défaut.
Colonne calculée
Une colonne calculée dans une requête est une colonne de sortie dont la valeur est calculée pour chaque ligne, sans modifier les données stockées.
Le résultat peut afficher quantity * unit_price AS line_total même si la table n’a pas de colonne line_total.
Comparaison sûre avec NULL
Une comparaison sûre avec NULL donne un résultat de comparaison certain même pour des entrées manquantes et peut considérer deux valeurs NULL comme égales.
NULL IS NOT DISTINCT FROM NULL vaut TRUE dans PostgreSQL et dans SQLite à partir de la version 3.39.
Concaténation
La concaténation assemble des parties de texte bout à bout, en conservant leurs caractères et en exigeant de fournir tout séparateur souhaité.
first_name || ' ' || last_name insère un espace entre les deux parties enregistrées du nom.
Conversion explicite
Une conversion explicite est un changement de type demandé par la requête, généralement avec CAST, afin de rendre l’opération voulue explicite.
L’expression CAST(quantity AS REAL) / 4 change l’opérande SQLite avant que la division ne puisse faire perdre une fraction.
Conversion implicite
Une conversion implicite est un changement de type effectué automatiquement par la base de données lors du traitement d’une opération ou d’une expression.
SQLite et PostgreSQL convertissent 42 en texte dans 'Order #' || 42, ce qui produit le libellé 'Order #42'.

D

DATE
DATE est un type de données pour un jour du calendrier dans PostgreSQL et le SQL standard ; il ne comporte pas d’heure.
DATE '2026-03-14' désigne explicitement le 14 mars 2026 comme une valeur de date PostgreSQL.
Division entière
La division entière divise des opérandes entiers et supprime la partie fractionnaire par troncation vers zéro dans SQLite et PostgreSQL.
Une requête utilisant 7 / 2 produit 3 ; rendre le deuxième opérande 2.0 conserve la fraction et produit 3.5.

E

Expression
Une expression combine des valeurs, des noms de colonnes, des opérateurs ou des appels de fonctions pour produire une valeur que SQL peut utiliser.
Dans une requête de commandes, quantity * unit_price est une expression qui produit le montant de la ligne pour chaque ligne.
EXTRACT
EXTRACT est une fonction SQL standard qui extrait une composante nommée, comme l’année ou le mois, d’une valeur de date et d’heure sous forme de nombre.
EXTRACT(MONTH FROM DATE '2026-03-14') dans PostgreSQL renvoie la valeur numérique de mois 3.

F

FLOOR
FLOOR est une fonction numérique qui renvoie le plus grand entier inférieur ou égal à son entrée, en allant vers les valeurs plus petites.
Pour une entrée négative, FLOOR(-4.1) vaut -5 : le résultat diffère donc d’une simple suppression de la partie fractionnaire.
Fonction monoligne
Une fonction monoligne renvoie une valeur pour chaque ligne d’entrée ; elle est aussi appelée fonction scalaire et ne regroupe pas les lignes.
L’utilisation de UPPER(city) dans SELECT modifie le texte de la ville affichée pour chaque client renvoyé par la requête.
Format de date ISO
Le format de date ISO AAAA-MM-JJ place l’année, le mois et le jour de largeur fixe par ordre décroissant d’unité et évite l’ambiguïté des formats locaux.
Le texte '2026-03-14' comporte des zéros initiaux et se trie avant '2026-11-02' dans l’ordre des dates.

I

Imbrication de fonctions
L’imbrication de fonctions place un appel de fonction à l’intérieur d’un autre, de sorte que le résultat intérieur devient un argument de l’appel qui l’englobe.
Dans ROUND(COALESCE(amount, 0), 2), la valeur de repli est déterminée avant que la fonction d’arrondi ne reçoive son entrée.
Indicateur numérique
Un indicateur numérique est une sortie comme 1 ou 0 qui indique si une condition donnée était vraie pour une ligne.
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END attribue zéro aux remises manquantes ainsi qu’aux remises non positives.
INSTR
INSTR est une fonction SQLite qui renvoie la première position d’une chaîne recherchée dans un texte, ou zéro s’il n’y a pas de correspondance.
INSTR('ana@example.com', '@') donne 4, tandis qu’une chaîne sans @ produit zéro.
Intervalle (interval)
Un intervalle est une valeur PostgreSQL qui représente une durée, comme un mois calendaire ou la différence entre des horodatages.
Ajouter INTERVAL '1 month' à une DATE PostgreSQL renvoie un horodatage et suit sa règle de fin de mois.
IS NULL
IS NULL est un test de valeur manquante qui renvoie TRUE lorsque son opérande est NULL et FALSE lorsqu’une valeur est présente.
WHERE phone IS NULL extrait les clients sans téléphone enregistré sans comparer une valeur à NULL par égalité.

J

Jour julien
Un jour julien représente une date et une heure sous forme d’un nombre de jours ; soustraire deux valeurs mesure les jours écoulés.
SQLite utilise julianday(end_date) - julianday(start_date) au lieu de soustraire directement des chaînes de dates ISO.

L

LENGTH
LENGTH compte les caractères du texte, espaces compris, dans SQLite et PostgreSQL ; une chaîne vide a une longueur nulle et NULL renvoie NULL.
LENGTH(' Bo ') donne 4 car les deux espaces aux extrémités comptent aussi bien que les deux lettres.
Libellé de mois
Un libellé de mois est une représentation textuelle d’une année et d’un mois qui identifie une période de rapport sans fusionner les années.
Le libellé '2026-03' distingue mars 2026 de mars 2025 dans l’affichage d’un rapport.
Littéral
Un littéral est une valeur écrite directement en SQL, comme un nombre ou du texte entre apostrophes, au lieu d’être lue dans une colonne.
L’espace dans first_name || ' ' || last_name est un littéral textuel fourni par la requête.
Logique à trois valeurs
La logique à trois valeurs combine TRUE, FALSE et UNKNOWN dans les conditions SQL : la négation ne produit donc pas toujours un résultat connu.
FALSE AND UNKNOWN vaut FALSE, mais TRUE AND UNKNOWN reste UNKNOWN car la deuxième condition est indéterminée.

M

Modèle de format
Un modèle de format précise quelles composantes de date et d’heure afficher et comment les organiser, à l’aide de symboles définis par la base de données.
SQLite utilise '%m/%d/%Y' pour un libellé de date américain ; TO_CHAR dans PostgreSQL utilise 'MM/DD/YYYY'.
Modulo
Le modulo renvoie le reste d’une division et s’écrit avec % dans SQLite et PostgreSQL ou MOD dans plusieurs dialectes.
Pour 135 minutes, 135 % 60 donne les 15 minutes restantes après deux heures complètes.

N

Nombre à virgule flottante
Un nombre à virgule flottante est une représentation numérique approximative qui peut introduire de petites erreurs lors du stockage de fractions décimales.
Dans SQLite, 0.1 + 0.2 = 0.3 peut être faux parce que la somme des approximations stockées n’est pas égale à la même valeur.
NULL
NULL est un marqueur de valeur manquante ou inconnue, distinct de zéro et, dans SQLite et PostgreSQL, d’une chaîne vide.
Une prime manquante rend salary + bonus inconnu même si le salaire de l’employé est enregistré.
NULLIF
NULLIF est une fonction SQL standard qui renvoie NULL lorsque ses deux arguments sont égaux et renvoie le premier argument sinon.
NULLIF(visits, 0) conserve les nombres de visites positifs mais transforme zéro en diviseur manquant pour un taux.

O

Ordre logique d’une requête
L’ordre logique d’une requête décrit comment les clauses construisent un résultat : FROM choisit les lignes, WHERE filtre, SELECT calcule et ORDER BY trie.
Un alias de sortie est disponible pour ORDER BY, mais une condition WHERE portable répète l’expression calculée associée à cet alias.

P

Plage semi-ouverte
Une plage semi-ouverte inclut sa borne de début et exclut sa borne de fin, ce qui permet à des périodes d’horodatages adjacentes de s’enchaîner.
ordered_at >= '2026-03-01' AND ordered_at < '2026-04-01' inclut tous les horodatages de mars.
Position d’un caractère
La position d’un caractère indique où se trouve un caractère dans une chaîne ; les positions du texte SQL commencent à 1 et comptent les espaces.
Le @ dans 'ana@example.com' est à la position 4, donc le domaine commence à la position 5.
Priorité des opérateurs
La priorité des opérateurs est la hiérarchie qui détermine quelles opérations ont lieu en premier lorsqu’aucune parenthèse ne modifie l’ordre d’une expression.
SQL multiplie avant d’additionner dans 10 + 3 * 2, donc le résultat est 16 et non 26.

R

Rang de tri personnalisé
Un rang de tri personnalisé attribue des positions numériques aux valeurs pour que ORDER BY suive une séquence voulue au lieu de l’ordre alphabétique.
Un CASE de priorité associe high à 1, medium à 2 et low à 3, puis trie le résultat par ordre croissant.
Remplissage
Le remplissage ajoute des caractères de remplissage pour atteindre une largeur de chaîne choisie ; une opération à largeur fixe peut aussi tronquer une valeur trop longue.
LPAD('42', 5, '0') dans PostgreSQL renvoie '00042', ce qui donne cinq caractères à un code court.
REPLACE
REPLACE est une fonction de chaînes qui remplace chaque occurrence exacte d’un fragment de texte par un autre dans la valeur renvoyée.
REPLACE('555-0100', '-', '') supprime le tiret et affiche '5550100' sans modifier la table.
Requête de rapport
Une requête de rapport sélectionne et présente des données dans un but donné, en combinant souvent des montants calculés, des libellés nettoyés, des dates et des classements.
Un rapport de commandes peut afficher un total net à côté d’un mois de commande et d’un libellé CASE pour la rapidité d’expédition.
ROUND
ROUND est une fonction numérique qui choisit la valeur la plus proche à la précision décimale demandée, avec des règles pour les valeurs à mi-chemin qui dépendent du type.
Le rapport utilise ROUND((price - cost) / price * 100, 1) pour afficher une marge à une décimale.

S

Sous-chaîne
Une sous-chaîne est une partie continue d’une chaîne, extraite à l’aide d’une position de départ et, si nécessaire, d’un nombre de caractères.
SUBSTR('Boston', 1, 3) renvoie 'Bos', en prenant trois caractères à partir de la première position.
strftime
strftime est une fonction de date et d’heure SQLite qui renvoie du texte sélectionné par un modèle de format, y compris des composantes de date précédées de zéros.
strftime('%m', '2026-03-14') renvoie '03', qui doit être comparé à du texte ou converti avant un usage numérique.

T

Temps Unix
Le temps Unix mesure le temps en secondes à partir d’une origine UTC fixe ; les différences entre temps Unix peuvent être converties en heures écoulées.
SQLite soustrait deux résultats unixepoch et divise par 3600.0 pour conserver les fractions d’heure dans une durée.
TIMESTAMP
Un TIMESTAMP contient une date et une heure, ce qui permet à une requête de distinguer des instants au sein d’un même jour du calendrier.
Un enregistrement à '2026-03-31 14:05:00' est postérieur à minuit au début du 31 mars.
TRIM
TRIM est une fonction de chaînes qui supprime par défaut les espaces aux deux extrémités tout en laissant inchangés les espaces à l’intérieur du texte.
Après TRIM(' New York '), les deux espaces entre les mots restent dans le texte renvoyé.
Type de données
Un type de données décrit la nature d’une valeur et contribue à déterminer les opérations, conversions, comparaisons et règles de tri applicables.
Le littéral textuel '42' et l’entier 42 peuvent se ressembler dans une grille tout en se comportant différemment en SQL.

U

UNKNOWN
UNKNOWN est le troisième résultat possible d’une condition SQL, produit lorsque des informations manquantes empêchent une comparaison d’être certainement vraie ou fausse.
La condition bonus = NULL vaut UNKNOWN : elle ne peut donc pas identifier une prime manquante dans un filtre WHERE.
UTC
UTC est la référence temporelle commune utilisée par SQLite pour CURRENT_DATE et CURRENT_TIMESTAMP ; la date obtenue peut différer de la date calendaire locale.
Un rapport établi près de minuit local peut afficher un jour différent s’il utilise CURRENT_DATE dans SQLite au lieu de localtime.

V

Valeur de repli
Une valeur de repli est le remplacement choisi lorsque la donnée préférée est manquante ; elle doit convenir au sens et au type de la sortie.
Un rapport peut utiliser zéro pour une prime non versée tout en laissant une note non enregistrée manquante au lieu d’inventer une note.
Valeur de repli ELSE
Une valeur de repli ELSE est le résultat de CASE utilisé lorsqu’aucune condition WHEN ne vaut TRUE, y compris lorsque les conditions valent UNKNOWN.
Un total NULL peut atteindre ELSE 'large' sauf si une branche précédente teste explicitement total IS NULL.
Valeur factice
Une valeur factice est une valeur enregistrée qui représente une information manquante, comme une chaîne vide, et qui peut devoir être convertie en NULL.
NULLIF(phone, '') transforme une chaîne de téléphone vide en NULL avant de fournir un libellé d’affichage.
Valeur limite
Une valeur limite se trouve au seuil entre des catégories : le choix de < ou <= détermine donc la catégorie qui la contient.
Au seuil 50, total < 50 est faux ; remplacer le test par total <= 50 le rend vrai.
Vérification par échantillon
Une vérification par échantillon compare les sorties calculées à des résultats obtenus à la main pour quelques lignes connues avant de se fier au rapport complet.
Ajouter LIMIT 5 pendant la construction du rapport facilite le repérage d’un espace manquant ou d’une erreur de division entière.

À propos de cette unité

Par StudeliSignaler une erreur

Crée ton propre Matériel d'Étude

Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.

Commencer