Requêtes SELECT en SQL : filtrer et trier
DébutantUnité 2 sur 6 de la formation Formation : SQL : requêtes SELECT, jointures et agrégation
Ce que tu vas apprendre
- Écris des requêtes qui lisent les colonnes choisies dans une table, comprends le jeu de résultats qu’elles renvoient et liste les valeurs différentes d’une colonne avec DISTINCT.
- Écrire une requête SELECT simpleNomme les colonnes à afficher avec SELECT et la table à lire avec FROM, respecte les règles de syntaxe de base et comprends la forme du résultat.
- Lister les valeurs différentes avec DISTINCTSupprime les lignes répétées d’un résultat avec SELECT DISTINCT et prévois le nombre de lignes restantes, y compris en présence de plusieurs colonnes ou de valeurs manquantes.
- Écrire une requête SELECT simple
- Ne conserve que les lignes qui répondent à une question en écrivant des conditions avec des opérateurs de comparaison sur les nombres, les textes et les dates, et en combinant les conditions avec AND, OR et NOT.
- Comparer des nombres avec les opérateurs de comparaisonUtilise WHERE avec =, <>, <, >, <= et >= pour sélectionner les lignes selon des valeurs numériques et choisis l’opérateur adapté à la formulation d’une question.
- Comparer correctement des textes et des datesÉcris les valeurs textuelles et les dates sous la forme correcte, prévois l’effet de la casse, de l’ordre alphabétique et des formats de date sur une comparaison, et évite les erreurs courantes de guillemets et de dates.
- Combiner des conditions avec AND, OR et NOTRelie plusieurs conditions avec AND et OR, inverse une condition avec NOT et utilise des parenthèses pour que la requête teste exactement ce que demande la question.
- Comparer des nombres avec les opérateurs de comparaison
- Raccourcis et précise les conditions avec IN pour les listes de valeurs, BETWEEN pour les plages et LIKE pour les motifs de texte, ainsi que leurs formes avec NOT, en connaissant leurs pièges courants.
- Tester l’appartenance à une liste de valeurs avec INUtilise IN et NOT IN pour conserver les lignes dont la valeur fait partie ou non de plusieurs valeurs listées, et comprends comment les listes interagissent avec AND et les valeurs manquantes.
- Sélectionner une plage avec BETWEENUtilise BETWEEN et NOT BETWEEN pour des plages de nombres, de dates et de texte, en sachant que les deux bornes sont incluses et en repérant les erreurs que cela peut provoquer.
- Rechercher des motifs de texte avec LIKETrouve du texte qui commence ou se termine par certains caractères, ou qui les contient, avec LIKE et les caractères % et _, et gère la sensibilité à la casse, les caractères génériques littéraux et les valeurs manquantes.
- Tester l’appartenance à une liste de valeurs avec IN
- Reconnais NULL comme marqueur d’une valeur manquante, trouve-le avec IS NULL et IS NOT NULL, et prévois comment les valeurs manquantes modifient le résultat des autres types de conditions.
- Trouver les valeurs manquantes avec IS NULLDistingue NULL de zéro et d’une chaîne vide, et utilise IS NULL et IS NOT NULL pour trouver les lignes où une valeur est ou n’est pas enregistrée.
- Prévoir l’effet de NULL sur les conditionsApplique la logique à trois valeurs (vrai, faux, inconnu) aux comparaisons, à AND, OR, NOT, IN, BETWEEN et LIKE, et décide si les lignes contenant des valeurs manquantes doivent figurer dans une réponse.
- Trouver les valeurs manquantes avec IS NULL
- Place les lignes de résultat dans un ordre qui a un sens avec ORDER BY, trie selon plusieurs colonnes en gérant les ex aequo et les valeurs manquantes, et renvoie les premières lignes ou une page de lignes avec LIMIT et OFFSET.
- Trier les lignes avec ORDER BYTrie un résultat selon une colonne dans l’ordre croissant ou décroissant et prévois l’ordre des nombres, des dates et du texte.
- Trier selon plusieurs colonnes et gérer les ex aequo et les NULLTrie selon plusieurs colonnes en précisant le sens de tri de chacune, ajoute des critères de départage pour obtenir un ordre reproductible et contrôle l’emplacement des valeurs manquantes.
- Renvoyer les premières lignes et des pages avec LIMIT et OFFSETRenvoie les premières lignes d’un résultat trié avec LIMIT, saute des lignes avec OFFSET pour afficher les pages suivantes et écris la même demande dans d’autres dialectes SQL.
- Trier les lignes avec ORDER BY
- Combine toutes les clauses dans des requêtes correctes et lisibles, comprends l’ordre de traitement d’une requête et traduis des questions courantes en requêtes dont tu vérifies les résultats.
- Ordonner les clauses et comprendre l’exécution d’une requêteÉcris SELECT, FROM, WHERE, ORDER BY et LIMIT dans l’ordre requis et utilise l’ordre logique de traitement pour prévoir les données auxquelles chaque clause a accès.
- Traduire une question en requête et vérifier la réponseTraduis étape par étape une question courante en requête sur une seule table, puis vérifie le résultat aux limites et en présence de valeurs manquantes, de différences de casse et d’ex aequo.
- Ordonner les clauses et comprendre l’exécution d’une requête
Requêtes SELECT en SQL : cours
1Choisir les données à afficher
Une requête utile commence par le choix de la table et des colonnes qui répondent à ta question. Le résultat peut afficher tous les enregistrements, quelques champs de chaque enregistrement ou une liste de valeurs différentes. Tu travailleras avec deux petites tables pour pouvoir retrouver chaque résultat dans les données stockées. Lire attentivement les noms de colonnes et distinguer l’ordre des colonnes de celui des lignes facilitera la compréhension des filtres et des tris par la suite.
1.1 SELECT, FROM et la table de résultat
Une requête demande des données à une base de données. Une requête SELECT simple lit la table stockée sans la modifier. SELECT nomme les colonnes à afficher et FROM nomme la table à lire.
Les exemples de texte utilisent la comparaison d’égalité ordinaire, sensible à la casse, dans SQLite et PostgreSQL. Les réglages de collation peuvent modifier la comparaison et le tri du texte.
Deux tables pour travailler
La table employees contient les huit lignes suivantes. salary est le salaire annuel en dollars ; hire_date est du texte au format YYYY-MM-DD. NULL marque une valeur manquante.
| employee_id | first_name | last_name | department | city | salary | hire_date | phone |
|---|---|---|---|---|---|---|---|
| 1 | Ana | Lopez | Sales | Chicago | 52 000 | 2019-03-15 | 312-555-0147 |
| 2 | Ben | Carter | IT | Denver | 71 000 | 2021-07-01 | NULL |
| 3 | Chloe | Nguyen | Sales | Chicago | 48 000 | 2023-01-09 | 312-555-0198 |
| 4 | David | Kim | Marketing | Boston | 60 000 | 2020-11-23 | 617-555-0110 |
| 5 | Emma | Brown | Sales | Denver | 65 000 | 2018-05-30 | NULL |
| 6 | Farid | Haddad | IT | Chicago | 83 000 | 2017-09-12 | 312-555-0175 |
| 7 | Grace | Okafor | NULL | Boston | 45 000 | 2024-02-19 | 617-555-0133 |
| 8 | Hugo | O'Neill | Marketing | Chicago | 58 000 | 2022-08-05 | NULL |
La table products enregistre les prix en dollars et les stocks en unités dans l’entrepôt.
| product_id | name | category | price | stock |
|---|---|---|---|---|
| 1 | Desk Lamp | Lighting | 24,99 | 40 |
| 2 | Floor Lamp | Lighting | 89,00 | 12 |
| 3 | Lamp Shade | Lighting | 15,50 | 0 |
| 4 | Office Chair | Furniture | 149,00 | 8 |
| 5 | Standing Desk | Furniture | 349,00 | 5 |
| 6 | Desk Organizer | Storage | 18,75 | 60 |
| 7 | Bookshelf | Furniture | 120,00 | NULL |
| 8 | Paper Tray | Storage | 9,99 | 25 |
Lire la structure de la requête
SELECT city, first_name
FROM employees;
Le jeu de résultats est une autre table : huit lignes et deux colonnes, avec city en premier. Aucun filtre n’est présent, chaque employé fournit donc une ligne. SQL ne garantit aucun ordre des lignes tant que tu n’ajoutes pas ORDER BY.
SELECT * FROM products; affiche toutes les colonnes dans l’ordre défini par la table. L’astérisque est utile pour explorer. Dans une requête enregistrée, nommer les colonnes permet de cibler le résultat et évite qu’une colonne ajoutée à la table en modifie la structure.
Rendre la syntaxe lisible
Sépare les colonnes par des virgules, sans virgule finale avant FROM. Termine l’instruction par un point-virgule. Les mots-clés ne sont pas sensibles à la casse : select fonctionne, mais les majuscules permettent de repérer facilement les clauses. Les espaces et les retours à la ligne séparent les mots ; ils ne changent pas le sens de cette requête. Un commentaire -- se poursuit jusqu’à la fin de sa ligne.
Les noms doivent correspondre au schéma. Si frist_name provoque une erreur de colonne introuvable, compare son orthographe à celle de first_name. SQL standard utilise des guillemets doubles pour les noms qui contiennent des espaces ou des mots réservés, comme "order date". PostgreSQL convertit en minuscules les noms sans guillemets, tandis que "City" recherche exactement ce nom avec sa majuscule. MySQL utilise normalement des accents graves ; les guillemets doubles délimitent les noms dans son mode ANSI_QUOTES. SQL Server accepte aussi les crochets et accepte les guillemets doubles lorsque QUOTED_IDENTIFIER est activé, ce qui est le cas par défaut.
Points clés
SELECTchoisit les colonnes affichées ;FROMindique leur table.- Les colonnes du résultat suivent la liste SELECT ; l’ordre des lignes nécessite
ORDER BY. SELECT *affiche toutes les colonnes ; des noms explicites ciblent les requêtes enregistrées.- Utilise des virgules entre les colonnes et un point-virgule pour terminer une instruction.
- Vérifie les noms dans le schéma et respecte les règles de la base de données pour délimiter les noms.
1.2 Valeurs différentes et combinaisons différentes
Une valeur répétée dans le résultat d’une requête est souvent utile. Plusieurs employés peuvent vivre dans la même ville et chacun doit tout de même avoir une ligne. Utilise DISTINCT lorsque la question demande des valeurs ou des combinaisons différentes.
Choisir ce qui compte comme doublon
SELECT DISTINCT city
FROM employees;
Le résultat contient Chicago, Denver et Boston, sans ordre garanti. Un simple SELECT city renverrait huit lignes, car chaque employé fournit une ville. L’ajout de DISTINCT réduit cet affichage à trois valeurs différentes. Les huit enregistrements des employés restent stockés.
La comparaison porte sur toutes les colonnes sélectionnées. Considère :
SELECT DISTINCT department, city
FROM employees;
Ana et Chloe fournissent toutes deux (Sales, Chicago) : cette paire apparaît donc une fois. Emma fournit (Sales, Denver), qui est différente et reste présente. Les autres paires sont (IT, Denver), (Marketing, Boston), (IT, Chicago), (NULL, Boston) et (Marketing, Chicago). Le résultat comporte sept lignes. Des services sont répétés, car un service associé à une autre ville forme une ligne de résultat différente.
Écris DISTINCT une seule fois, immédiatement après SELECT. Il s’applique à toute la ligne sélectionnée. Le placer entre des noms de colonnes, comme dans SELECT department, DISTINCT city, provoque une erreur de syntaxe.
Faire attention aux colonnes incluses
Si tu ajoutes employee_id aux colonnes sélectionnées, chaque ligne devient différente. SELECT DISTINCT employee_id, city FROM employees; renvoie toujours huit lignes : chaque identifiant est unique, même lorsque la ville se répète. Pour répondre à « Dans quelles villes y a-t-il des employés ? », sélectionne uniquement la ville. Pour répondre à « Quels employés vivent dans chaque ville ? », conserve les colonnes d’identification et attends-toi à des villes répétées.
Lors de cette suppression des doublons, les NULL répétés sont traités comme des doublons. SELECT DISTINCT department FROM employees; renvoie Sales, IT, Marketing et une ligne NULL. La ligne NULL indique qu’un service est manquant ; ce n’est pas un quatrième nom de service. Cette règle sur les doublons diffère de NULL = NULL, qui donne inconnu dans un filtre.
Les comparaisons de texte suivent une collation, c’est-à-dire les règles de la base de données pour comparer et ordonner le texte. Avec les comparaisons ordinaires sensibles à la casse utilisées dans ces exemples SQLite et PostgreSQL, Chicago et chicago sont des valeurs différentes. Une liste DISTINCT peut révéler une casse incohérente. Supprimer les répétitions de l’affichage ne corrige pas l’orthographe des données stockées.
Combiner DISTINCT avec une courte liste triée
SELECT DISTINCT city
FROM employees
ORDER BY city
LIMIT 2;
D’abord, les villes en double disparaissent. Ensuite, les trois villes sont triées. Enfin, deux lignes restent dans le résultat : Boston et Chicago, dans cet ordre. Appliquer d’abord la limite aux lignes des employés répondrait à une autre question.
Dans une requête DISTINCT, conserve les colonnes de tri dans la liste SELECT. PostgreSQL l’exige ; SQLite autorise certaines requêtes qui trient selon une colonne non sélectionnée, mais le choix entre différentes valeurs masquées rend leur ordre difficile à interpréter. Si un résultat contient des répétitions inattendues, examine les colonnes sélectionnées avant de décider si DISTINCT a sa place dans la requête.
Points clés
DISTINCTsupprime les lignes de résultat entièrement en double sans modifier les lignes stockées.- Ajouter des colonnes change les lignes considérées comme des doublons ; une clé unique rend chaque ligne différente.
- DISTINCT regroupe les NULL répétés.
- Les doublons sont supprimés avant la limitation du résultat trié.
2Conserver les lignes qui répondent à la question
Le filtrage transforme une table en réponse portant sur certains enregistrements : une plage de salaires, une ville ou un groupe qui remplit plusieurs conditions. De petits choix comptent, notamment l’inclusion ou non d’une borne et l’obligation ou non de satisfaire deux conditions à la fois. Les comparaisons numériques, les valeurs textuelles et les dates, ainsi que les conditions logiques regroupées ont chacune leurs règles. Une requête peut s’exécuter correctement tout en posant la mauvaise question : tu examineras donc les lignes qui passent chaque test.
2.1 Nombres et valeurs limites
La clause WHERE ne conserve une ligne que lorsque sa condition est vraie. Elle suit FROM et peut tester n’importe quelle colonne de la table, y compris une colonne que tu n’affiches pas.
Associer la formulation à l’opérateur
| Demande | Opérateur | Exemple de condition |
|---|---|---|
| Égal à | = | stock = 0 |
| Différent de | <> | stock <> 0 |
| Plus de | > | salary > 60000 |
| Au moins | >= | salary >= 60000 |
| Moins de | < | price < 20.50 |
| Au plus | <= | price <= 20.50 |
<> est l’écriture de « différent de » en SQL standard. Les cinq bases de données présentées ici acceptent aussi !=. Utilise un seul signe égal pour l’égalité. SQLite accepte ==, mais PostgreSQL refuse cette forme.
Examiner une ligne située sur une borne
SELECT first_name, salary
FROM employees
WHERE salary > 60000;
Ben a 71 000, Emma a 65 000 et Farid a 83 000. Ce sont les trois lignes qui remplissent la condition, sans ordre précisé. David gagne exactement 60 000. Sa ligne ne satisfait pas > 60000, car « plus de » exclut l’égalité.
Remplace uniquement l’opérateur par >=. David rejoint alors le résultat, qui compte quatre lignes. C’est la différence entre « au moins 60 000 » et « plus de 60 000 ». Pour vérifier une borne, demande-toi ce qui arrive à une valeur exactement égale au seuil ; des valeurs bien supérieures ne peuvent pas révéler cette erreur.
Pour « au plus 20,50 », un prix de 20,50 satisfait la condition et un prix de 20,51 ne la satisfait pas. Lorsqu’une demande donne une borne inférieure et une borne supérieure, vérifie chaque extrémité séparément avant de relier les tests.
Écrire les valeurs numériques comme des nombres
Utilise des chiffres sans ajout dans les conditions SQL : 60000, sans virgule de milliers ni symbole monétaire. Une virgule sépare les éléments SQL ; WHERE salary > 60,000 est une erreur de syntaxe. Les valeurs décimales utilisent un point, comme dans WHERE price < 20.50. Les salaires et les prix doivent figurer dans des colonnes numériques pour que les comparaisons tiennent compte de leur valeur numérique.
Un texte qui ressemble à un nombre suit les règles du texte lorsqu’il est comparé comme tel. La valeur textuelle '9' se classe après '10', car son premier caractère vient plus tard. Cela concerne les caractères et ne signifie pas que neuf est supérieur à dix. Lis le type de données de la colonne avant d’interpréter une comparaison inattendue.
Filtrer sans afficher la colonne testée
SELECT first_name
FROM employees
WHERE salary < 50000;
Chloe et Grace satisfont la condition. Leur salaire sert à tester les lignes, mais il est absent du résultat. Tu n’as pas besoin d’ajouter le salaire à SELECT pour que le filtre fonctionne. Lors de la vérification d’une requête, l’afficher temporairement peut t’aider à comprendre pourquoi chaque ligne a été retenue.
Une égalité sur une clé primaire permet de rechercher directement un enregistrement : WHERE employee_id = 6 trouve Farid. Une clé primaire identifie une ligne ; cette égalité ne peut donc pas renvoyer plusieurs employés ayant le même identifiant.
Les données manquantes demandent une attention particulière. WHERE stock <> 0 renvoie six produits. Lamp Shade est exclu, car son stock connu est nul. Bookshelf est également exclu : son stock est NULL, donc la comparaison est inconnue et WHERE ne conserve pas la ligne. Un test « différent de » n’ajoute pas les valeurs manquantes à son résultat.
Points clés
- WHERE ne conserve que les lignes dont la condition est vraie.
>et<excluent leurs seuils ;>=et<=les incluent.- Écris les littéraux numériques sans symbole monétaire, guillemets ni séparateur de milliers.
- Un filtre peut tester une colonne qui n’est pas affichée.
- Utilise une égalité sur une clé pour rechercher un enregistrement.
- Les comparaisons ordinaires avec NULL ne satisfont pas un filtre WHERE.
2.2 Texte, guillemets et dates complètes
Les conditions sur le texte et les dates nécessitent des valeurs sous une forme que la base de données peut interpréter. Une valeur mal orthographiée peut ne renvoyer aucune ligne sans avertissement, tandis qu’une apostrophe manquante peut transformer cette valeur en nom de colonne.
Distinguer une valeur d’un nom
SELECT first_name
FROM employees
WHERE city = 'Chicago';
Les apostrophes font de 'Chicago' une valeur textuelle. Le résultat contient Ana, Chloe, Farid et Hugo. Sans apostrophes, Chicago est lu comme un nom : la base de données recherche donc une colonne portant ce nom. En SQL standard, les guillemets doubles délimitent aussi des noms. PostgreSQL refuse city = "Chicago" lorsqu’une telle colonne n’existe pas. Certaines configurations SQLite acceptent les chaînes entre guillemets doubles par compatibilité avec d’anciens usages ; utilise systématiquement des apostrophes pour les valeurs.
Une apostrophe à l’intérieur d’une valeur est doublée :
SELECT first_name
FROM employees
WHERE last_name = 'O''Neill';
Cette requête trouve Hugo. Les deux apostrophes consécutives représentent une apostrophe à l’intérieur de la valeur ; les apostrophes extérieures en marquent le début et la fin. SQL standard n’utilise pas de barre oblique inverse pour échapper cette apostrophe.
Vérifier les règles de comparaison
Une collation détermine l’égalité et le tri du texte, notamment le traitement de la casse et des lettres accentuées. Dans les comparaisons ordinaires sensibles à la casse de SQLite et PostgreSQL utilisées ici, 'Chicago' et 'chicago' sont différents. WHERE city = 'chicago' ne renvoie aucune ligne. MySQL et SQL Server utilisent souvent des collations insensibles à la casse ; leurs réglages habituels peuvent donc trouver les deux écritures.
Les comparaisons de plages de texte suivent aussi la collation. Avec ces noms, WHERE last_name < 'M' renvoie Brown, Carter, Haddad, Kim et Lopez. Les valeurs sont comparées à partir de la gauche. Une valeur plus longue qui commence par les mêmes caractères vient après son préfixe : 'Martin' vient après 'M'. Une limite fixée à 'M' n’équivaut pas à « tous les noms commençant par M ».
Placer l’année en premier
La colonne hire_date de l’exemple stocke des dates complètes sous forme de texte : année, mois, puis jour, avec des largeurs fixes. L’ordre du texte correspond ainsi à l’ordre chronologique.
SELECT first_name, hire_date
FROM employees
WHERE hire_date >= '2022-01-01';
Chloe, Grace et Hugo satisfont la condition. PostgreSQL possède aussi un véritable type DATE qui accepte ce littéral. Sa forme standard avec indication du type est DATE '2022-01-01' ; SQLite n’utilise pas cette syntaxe de littéral typé.
Une date dans un format local comme '03/04/2024' est ambiguë dans une colonne de dates, car les réglages peuvent en faire le 4 mars ou le 3 avril. Stockées sous forme de texte, les dates qui commencent par le mois sont comparées par mois avant l’année. Par exemple, '12/01/2021' se classe après '03/15/2024', alors que la première date est chronologiquement antérieure.
Traduire la borne avec une date complète
« Embauché après 2022 » signifie à partir du '2023-01-01'. Comparer le texte à '2022' admet aussi la date de Hugo, '2022-08-05' : le texte plus long se classe après le préfixe correspondant.
Si une colonne contient des heures, l’égalité avec une date seule ne sélectionne pas toutes les heures de cette journée. Pour inclure le 31 mars 2024, utilise ordered_at >= '2024-03-31' AND ordered_at < '2024-04-01'. Cela conserve toutes les heures à partir du début du 31 mars jusqu’au début du 1er avril, exclu.
Points clés
- Utilise des apostrophes pour les valeurs textuelles ; double une apostrophe à l’intérieur d’une valeur.
- La collation détermine la manière dont la casse et les caractères sont comparés.
- Utilise des dates complètes
YYYY-MM-DDpour que les dates textuelles de largeur fixe soient triées chronologiquement. - Pour couvrir une journée entière avec des heures, inclus son début et exclus celui du jour suivant.
2.3 AND, OR, NOT et conditions regroupées
Une ligne peut devoir satisfaire plusieurs tests. AND exige que les deux conditions soient vraies. OR exige qu’au moins une soit vraie. NOT inverse vrai et faux ; lorsqu’une condition est inconnue à cause de NULL, NOT la laisse inconnue.
Déterminer si les deux tests doivent être satisfaits
SELECT first_name
FROM employees
WHERE department = 'Sales' AND city = 'Chicago';
Ana et Chloe satisfont les deux tests. Emma travaille dans Sales mais vit à Denver : elle ne satisfait donc pas cette condition AND. Remplacer AND par OR admet aussi Emma, Farid et Hugo : les cinq employés retenus satisfont l’un des tests ou les deux.
Ajouter une condition AND peut laisser le résultat inchangé ou le réduire. Ajouter une condition OR peut le laisser inchangé ou l’élargir. Cela te permet de vérifier rapidement un filtre construit par étapes.
Chaque comparaison doit être complète. Écris department = 'IT' OR department = 'Marketing', en répétant la colonne et l’opérateur. department = 'IT' OR 'Marketing' n’exprime pas la deuxième comparaison. PostgreSQL le refuse ; SQLite traite le texte seul comme faux et ne renvoie que le personnel de IT. De même, écris salary > 50000 AND salary < 70000, avec le salaire des deux côtés de AND.
Traduire des groupes de possibilités
« Les employés de Boston et de Denver » désigne généralement les personnes de l’une ou l’autre ville. Chaque ligne ne contient qu’une ville : utilise donc city = 'Boston' OR city = 'Denver'. Cette condition renvoie Ben, David, Emma et Grace. Un AND entre ces égalités exige qu’une même valeur de ville désigne les deux lieux à la fois et ne renvoie aucune ligne.
Lorsque les opérateurs sont mélangés, NOT est évalué avant AND, et AND avant OR. Sans parenthèses :
WHERE department = 'Sales'
OR department = 'Marketing' AND city = 'Chicago'
Cela désigne le personnel de Sales, quelle que soit sa ville, ainsi que le personnel de Marketing à Chicago. Emma satisfait la condition, car la comparaison avec Sales suffit. Pour limiter les deux services à Chicago, regroupe les possibilités :
SELECT first_name
FROM employees
WHERE (department = 'Sales' OR department = 'Marketing')
AND city = 'Chicago';
Ana, Chloe et Hugo satisfont maintenant la condition. Les parenthèses soumettent les deux choix de service à une même exigence concernant la ville. Utilise-les pour clarifier un filtre qui mélange AND et OR, même lorsque l’ordre par défaut convient déjà.
Inverser tout un groupe
NOT (city = 'Chicago' OR city = 'Denver') renvoie David et Grace à Boston. Aucune des villes indiquées n’est acceptée. Pour ces valeurs, cette condition équivaut à city <> 'Chicago' AND city <> 'Denver'.
Utiliser OR entre ces deux tests « différent de » est un piège courant. Une ligne de Chicago diffère de Denver et une ligne de Denver diffère de Chicago. Chaque employé dont la ville est enregistrée satisfait au moins un des tests : le OR n’exclut donc aucune des deux villes.
Construis une condition complexe étape par étape. Vérifie les lignes après le premier test, puis après l’ajout du suivant. Tu peux inverser les deux côtés d’un AND ou les deux côtés d’un OR sans changer la réponse ; choisis la disposition qui rend les groupes les plus faciles à lire.
Points clés
- AND exige les deux conditions ; OR en exige au moins une.
- Écris une comparaison complète de chaque côté d’un opérateur logique.
- NOT est évalué avant AND, puis OR ; les parenthèses rendent le regroupement voulu explicite.
- Des possibilités pour une même colonne nécessitent généralement OR, même si la demande dit « et ».
- Pour exclure chacune de deux correspondances, nie le groupe OR ou relie les deux exclusions avec AND.
3Filtrer par listes, plages et motifs de texte
Certaines questions demandent plusieurs choix exacts, d’autres une plage de valeurs ou une partie d’un nom. IN, BETWEEN et LIKE donnent une forme claire à chaque type de demande. Pour choisir entre eux, détermine ce qu’une correspondance signifie : une valeur entière, une valeur comprise entre des bornes ou un texte conforme à un motif. Tu examineras aussi les valeurs manquantes et les détails qui changent une réponse, notamment l’inclusion des bornes, la place des caractères génériques et la sensibilité à la casse.
3.1 Listes de choix exacts avec IN
Utilise IN lorsqu’une colonne peut correspondre à l’une des valeurs d’une liste. Il raccourcit un groupe d’égalités reliées par OR tout en conservant leur sens.
Construire une liste de possibilités
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing');
Ben, David, Farid et Hugo satisfont la condition. Chacun a l’une des deux valeurs de service. Le même test pourrait s’écrire department = 'IT' OR department = 'Marketing'.
Place les éléments de la liste entre parenthèses, séparés par des virgules. Mets le texte entre apostrophes ; laisse les valeurs numériques sans apostrophes. Par exemple, employee_id IN (2, 4, 6) sélectionne Ben, David et Farid. L’ordre des éléments de la liste ne trie pas le résultat. Répéter un élément ne répète pas une ligne correspondante : IN (6, 2, 2, 4) sélectionne les mêmes enregistrements. Utilise ORDER BY si tu as besoin d’ordonner le résultat.
IN compare des valeurs entières selon les mêmes règles que l’égalité. city IN ('Chi') ne correspond pas à Chicago. Avec les comparaisons ordinaires sensibles à la casse utilisées ici, city IN ('chicago') ne lui correspond pas non plus. La recherche d’un fragment nécessite LIKE, tandis que le traitement de la casse dépend de la collation.
Appliquer une autre règle à chaque choix
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing')
AND city = 'Chicago';
Farid et Hugo satisfont la condition. IN est une seule condition, donc AND applique le test sur la ville à tout le choix de services. Dans la version développée avec OR, mets les deux comparaisons de service entre parenthèses. Sans elles, department = 'IT' OR department = 'Marketing' AND city = 'Chicago' admet aussi Ben, car AND est prioritaire et la règle sur la ville ne s’applique qu’à Marketing.
Exclure les valeurs de la liste
WHERE city NOT IN ('Chicago', 'Denver') renvoie David et Grace. Une ville enregistrée ne satisfait la condition que si elle diffère des deux éléments. Cette forme est utile pour plusieurs exclusions et évite l’erreur qui consiste à relier des conditions « différent de » avec OR.
Les valeurs manquantes ne satisfont aucune des deux formes. Le service de Grace est NULL, donc department NOT IN ('Sales') ne l’inclut pas. La base de données ne peut pas établir que le service manquant diffère de Sales. Pour inclure aussi le personnel sans service attribué, écris department NOT IN ('Sales') OR department IS NULL.
Un NULL dans une liste NOT IN crée un problème plus large. department NOT IN ('Sales', NULL) exige à la fois department <> 'Sales' et department <> NULL. La deuxième comparaison est toujours inconnue, donc le test combiné n’est jamais vrai et WHERE ne renvoie aucune ligne. Sépare les tests de valeurs manquantes de la liste de valeurs.
Avec IN, une correspondance réelle réussit toujours même si un autre élément de la liste est NULL. department IN ('Sales', NULL) conserve les trois membres du personnel de Sales, mais n’ajoute pas Grace. Utilise IS NULL pour demander explicitement les valeurs manquantes.
Une liste IN ordinaire en SQL doit contenir au moins un élément. PostgreSQL refuse IN () ; SQLite l’accepte comme faux. Si un programme construit une liste à partir des choix de l’utilisateur, traite le cas d’une liste vide avant d’envoyer la requête afin que le comportement soit voulu dans toutes les bases de données.
Points clés
- IN vérifie si une valeur entière correspond à l’un des éléments de sa liste entre parenthèses, séparés par des virgules.
- L’ordre des éléments et leurs répétitions ne déterminent pas l’ordre du résultat et ne dupliquent pas les lignes correspondantes.
- IN se combine avec AND comme une seule condition.
- NOT IN exclut les valeurs de la liste, mais n’inclut pas les valeurs manquantes.
- Un NULL dans une liste NOT IN empêche toute ligne de satisfaire le test WHERE.
3.2 Plages et bornes incluses
BETWEEN teste une plage dont les deux bornes sont incluses. Utilise-le lorsque « de » et « à » incluent les valeurs limites indiquées ; utilise des comparaisons explicites lorsqu’une borne doit être exclue.
Vérifier les deux bornes
SELECT name, price
FROM products
WHERE price BETWEEN 15.50 AND 89.00;
Desk Lamp, Floor Lamp, Lamp Shade et Desk Organizer satisfont la condition. Floor Lamp coûte exactement 89,00 et Lamp Shade exactement 15,50 : les deux sont donc conservés. La condition signifie price >= 15.50 AND price <= 89.00.
Place la borne inférieure en premier. price BETWEEN 89.00 AND 15.50 demande un prix d’au moins 89,00 et d’au plus 15,50. La syntaxe est valide, mais aucune valeur ne correspond. BETWEEN ordinaire ne remet pas les bornes dans l’ordre pour toi. PostgreSQL propose BETWEEN SYMMETRIC pour le faire, mais utilise la forme avec la borne inférieure en premier pour une requête partagée avec SQLite.
Pour « plus de 15,50 et moins de 89,00 », écris price > 15.50 AND price < 89.00. Seuls Desk Lamp et Desk Organizer satisfont la condition. Cette différence concerne les bornes de la question, pas la façon dont le résultat est affiché.
À l’extérieur d’une plage
price NOT BETWEEN 20 AND 100 signifie price < 20 OR price > 100. Cette condition renvoie Lamp Shade, Office Chair, Standing Desk, Desk Organizer, Bookshelf et Paper Tray. Des valeurs égales à 20 ou à 100 seraient à l’intérieur de la plage initiale et ne satisferaient pas NOT BETWEEN.
Pour une valeur testée manquante, le résultat de chacun des deux tests est inconnu. Pour le stock, BETWEEN 5 AND 40 sélectionne cinq produits et NOT BETWEEN en sélectionne deux : Lamp Shade avec 0 et Desk Organizer avec 60. Le stock de Bookshelf est NULL et ne figure dans aucun des deux résultats. Une plage et sa négation ne couvrent donc pas nécessairement toutes les lignes stockées.
Dates et heures
Les dates complètes sous forme de texte dans l’ordre YYYY-MM-DD permettent de définir des plages de dates. hire_date BETWEEN '2020-01-01' AND '2022-12-31' sélectionne Ben, David et Hugo, en couvrant les trois années civiles dans cette colonne qui contient uniquement des dates.
Une colonne contenant des heures nécessite une autre borne supérieure pour couvrir un mois entier. Dans une colonne d’horodatage, une borne contenant seulement une date signifie minuit au début de ce jour. Sous forme de texte, même '2024-03-31 00:00:00' se classe après le préfixe plus court '2024-03-31'. Pour inclure toutes les heures de mars, utilise :
WHERE ordered_at >= '2024-03-01'
AND ordered_at < '2024-04-01'
Cette condition inclut le début de mars et s’arrête juste avant avril, sans avoir à deviner la dernière fraction de seconde du 31 mars.
Plages de texte et deux usages de AND
Les bornes textuelles sont des valeurs complètes. last_name BETWEEN 'A' AND 'C' inclut Brown mais exclut Carter, puisque Carter se classe après son préfixe C. Selon ces règles de texte, last_name >= 'A' AND last_name < 'D' couvre les noms commençant par A, B ou C et renvoie Brown et Carter.
Dans price BETWEEN 10 AND 100 AND category = 'Lighting', le premier AND sépare les bornes de la plage ; le second relie le test de plage au test de catégorie. Les produits correspondants sont Desk Lamp, Floor Lamp et Lamp Shade. Des retours à la ligne peuvent rendre les deux rôles plus visibles.
Points clés
- BETWEEN inclut les deux bornes et attend la borne inférieure en premier.
- NOT BETWEEN sélectionne les valeurs inférieures à la borne basse ou supérieures à la borne haute.
- Des comparaisons explicites permettent d’exclure une borne ou les deux.
- Pour couvrir un mois entier avec des heures, inclus son début et arrête-toi avant le mois suivant.
- Une borne textuelle est une valeur entière, et non toutes les valeurs commençant par cette lettre.
- Un NULL dans la colonne testée ne satisfait aucun des deux tests de plage.
3.3 Motifs de texte avec LIKE
LIKE compare du texte à un motif. Utilise-le pour rechercher un début, une fin ou un fragment lorsque l’égalité exigerait une valeur entière exacte.
Placer les caractères génériques
| Motif | Signification | Noms de produits correspondants |
|---|---|---|
'Lamp%' | Commence par Lamp | Lamp Shade |
'%Lamp' | Se termine par Lamp | Desk Lamp, Floor Lamp |
'%Lamp%' | Contient Lamp | Desk Lamp, Floor Lamp, Lamp Shade |
'Lamp' | Exactement Lamp | Aucun |
Le motif doit correspondre à la valeur entière. % peut représenter zéro caractère ou plus, y compris des espaces. Dans '%Lamp%', chaque signe pourcentage peut correspondre à une chaîne vide : le texte peut donc commencer ou se terminer par Lamp, mais aussi le contenir au milieu.
_ représente exactement un caractère. last_name LIKE '_im' trouve Kim. Les quatre tirets bas de first_name LIKE '____' trouvent Emma et Hugo, les prénoms qui comptent exactement quatre lettres. Le tiret bas ne représente pas un caractère facultatif.
SELECT first_name, phone
FROM employees
WHERE phone LIKE '312-%';
Ana, Chloe et Farid satisfont la condition, car leur numéro de téléphone enregistré commence par 312-. Le signe pourcentage couvre tous les caractères restants.
Choisir l’opérateur et la règle de casse
Les caractères génériques appartiennent aux motifs LIKE. name = '%Lamp%' recherche des signes pourcentage littéraux et ne renvoie ici aucun produit. Les caractères génériques * et ? utilisés dans la recherche de fichiers n’ont pas de signification particulière dans LIKE ; name LIKE 'Desk*' recherche un astérisque littéral après Desk.
LIKE dans SQLite ignore normalement la casse pour les lettres ASCII de A à Z, tandis que LIKE ordinaire dans PostgreSQL y est sensible. name LIKE '%desk%' trouve donc Desk Lamp, Standing Desk et Desk Organizer dans SQLite, mais aucun produit dans PostgreSQL avec une collation sensible à la casse. PostgreSQL propose aussi ILIKE, qui est insensible à la casse. Dans MySQL, le comportement suit la collation.
Pour les noms de produits ASCII utilisés ici, LOWER(name) LIKE '%desk%' donne les mêmes correspondances dans SQLite et PostgreSQL : LOWER convertit le nom en minuscules avant la recherche. Pour d’autres systèmes d’écriture, la conversion de casse dépend des règles de la base de données et de la langue. Dans SQLite, l’égalité diffère aussi de LIKE : city = 'chicago' ne trouve pas Chicago avec la collation binaire par défaut, alors que city LIKE 'chicago' le trouve.
Rechercher un véritable caractère générique
Pour rechercher un tiret bas littéral, choisis un caractère d’échappement :
WHERE code LIKE 'SPRING!_%' ESCAPE '!'
Dans une table de codes de réduction, ce motif correspond à 'SPRING_10' mais pas à 'SPRINGS10'. !_ représente un véritable tiret bas ; le dernier % correspond toujours à une séquence. Utilise la même méthode avec !% pour un signe pourcentage littéral. Écrire ESCAPE explicitement évite de dépendre des valeurs par défaut de la base de données ; PostgreSQL utilise normalement une barre oblique inverse et SQLite n’a pas de caractère d’échappement par défaut.
Négation et volume de recherche
name NOT LIKE '%Lamp%' renvoie les cinq autres produits. Un texte manquant ne satisfait ni LIKE ni NOT LIKE. Parmi les employés, trois numéros correspondent à '312-%', deux numéros enregistrés n’y correspondent pas et les trois numéros NULL n’apparaissent dans aucun des deux résultats.
Un % placé en début de motif ne fournit à un index ordinaire aucun début de texte fixe sur lequel restreindre la recherche : une grande partie de la table peut donc être parcourue. Un début fixe comme 'Desk%' peut aider un index adapté. Pour les dates, utilise des plages de dates : LIKE fonctionne sur ces dates textuelles, mais PostgreSQL exige une conversion avant d’appliquer LIKE à une véritable colonne DATE.
Points clés
- LIKE compare le motif à la valeur entière ;
%couvre un nombre quelconque de caractères et_exactement un. - Place
%au début, à la fin ou aux deux endroits pour déterminer où un fragment peut apparaître. - Le traitement de la casse varie selon la base de données et la collation ; LOWER aide avec ces noms ASCII.
- ESCAPE permet à un caractère générique de représenter son caractère littéral.
- NULL ne satisfait ni LIKE ni NOT LIKE.
- Les caractères génériques en début de motif peuvent obliger à parcourir davantage de données ; utilise des plages pour les dates.
4Tenir compte des valeurs manquantes
Les données manquantes modifient les enregistrements qu’un filtre peut trouver. Un stock nul, une chaîne vide pour un téléphone et une valeur non enregistrée indiquent des choses différentes, même si un outil de requête donne à certaines cellules la même apparence. Tu utiliseras des tests explicites de valeurs manquantes et suivras la troisième valeur de vérité : inconnu. Ces règles expliquent pourquoi un filtre et son contraire peuvent exclure les mêmes lignes et comment les inclure lorsque la question le demande.
4.1 NULL, zéro et chaîne vide
NULL marque une valeur manquante : une valeur peut être inconnue, non enregistrée ou sans objet. Il diffère d’un zéro connu ou d’un texte connu sans caractères.
Comprendre ce que signifie une valeur manquante
Lamp Shade a stock = 0. Sa quantité enregistrée est nulle : il est donc en rupture de stock. Bookshelf a un stock NULL : la quantité n’a pas été enregistrée. La base de données ne peut pas te dire s’il y a zéro unité ou un autre nombre.
Cette distinction change la question à laquelle tu peux répondre :
| Question | Condition | Résultat |
|---|---|---|
| Quels produits sont en rupture de stock ? | stock = 0 | Lamp Shade |
| Quelles quantités en stock sont inconnues ? | stock IS NULL | Bookshelf |
| Quelles quantités sont enregistrées ? | stock IS NOT NULL | Les sept autres produits |
Une cellule qui paraît vide dans un outil de requête ne suffit pas à distinguer ces états. Certains outils affichent NULL sous forme de cellule vide ; d’autres affichent NULL. Teste directement la valeur stockée.
Utiliser les tests de valeurs manquantes
SELECT first_name
FROM employees
WHERE phone IS NULL;
Ben, Emma et Hugo n’ont pas de numéro de téléphone enregistré. IS NULL donne vrai pour leurs valeurs manquantes. Pour trouver les cinq employés qui ont un numéro enregistré, utilise phone IS NOT NULL : Ana, Chloe, David, Farid et Grace.
N’écris pas phone = NULL pour trouver les numéros manquants. Une comparaison ordinaire impliquant NULL donne inconnu, même lorsque les deux côtés sont NULL. WHERE ne conserve que les lignes pour lesquelles la condition est vraie : = NULL n’en renvoie donc aucune. <> NULL pose le même problème. IS NULL teste la présence du marqueur de valeur manquante et donne une réponse déterminée, vraie ou fausse, pour ces valeurs d’une seule colonne.
La forme NOT phone IS NULL trouve aussi les numéros présents dans SQLite et PostgreSQL, mais phone IS NOT NULL rend le test voulu plus facile à lire.
Distinguer trois formes de texte
| Expression SQL | Ce qu’elle représente |
|---|---|
NULL | Une valeur manquante |
'' | Une valeur textuelle connue de zéro caractère |
'NULL' | Quatre lettres ordinaires |
SQLite, PostgreSQL, MySQL et SQL Server distinguent la chaîne vide de NULL. phone = '' trouverait les chaînes vides, pas les numéros manquants de Ben, Emma ou Hugo. Si une colonne peut contenir les deux, utilise phone IS NULL OR phone = '' pour trouver l’un ou l’autre état. Oracle traite une valeur textuelle vide comme NULL : cette distinction change donc lorsque tu passes d’une base de données à une autre.
Tenir compte de la formulation et du schéma
« Manquant », « non enregistré » et « non attribué » indiquent IS NULL. department IS NULL trouve Grace. Son service manquant ne signifie pas que le texte du service est le mot 'NULL', et ne permet pas non plus de déterminer son service.
La définition de la table peut déclarer une colonne NOT NULL, ce qui signifie qu’une ligne stockée ne peut pas contenir NULL dans cette colonne. Une requête IS NULL sur une telle colonne ne renvoie aucune ligne. Vérifie cette règle lorsque tu examines un schéma : les colonnes qui autorisent les données manquantes demandent une attention particulière lorsque tu construis des exclusions ou combines des conditions.
Points clés
- NULL est un marqueur de valeur manquante ; zéro et la chaîne vide sont des valeurs connues.
- IS NULL trouve les valeurs manquantes et IS NOT NULL les valeurs présentes.
= NULLet<> NULLne permettent pas de trouver des lignes par des comparaisons ordinaires.'NULL'entre apostrophes est du texte, et Oracle traite la chaîne vide différemment des autres bases présentées.- Une colonne NOT NULL ne peut pas stocker NULL.
4.2 Vrai, faux et inconnu
Une condition en SQL peut être vraie, fausse ou inconnue. Les valeurs manquantes rendent ce troisième état nécessaire : sans quantité enregistrée, une base de données ne peut pas établir si cette quantité dépasse un seuil.
Une condition et son contraire
Pour Bookshelf, stock > 10 est inconnu, car le stock est NULL. Il en va de même pour stock <= 10. WHERE ne conserve que les lignes dont la condition est vraie et exclut celles dont elle est fausse ou inconnue.
Dans la table des produits, stock > 10 renvoie quatre lignes et stock <= 10 en renvoie trois. Ensemble, elles couvrent sept des huit produits. Bookshelf est absent des deux résultats. Appliquer NOT ne le rétablit pas : la négation d’inconnu est inconnue, donc NOT (stock > 10) ne sélectionne toujours que les trois quantités connues qui valent au plus 10.
Le cas diffère pour une valeur qui ne satisfait pas une condition. Le zéro connu de Lamp Shade rend stock > 10 faux, donc NOT le rend vrai. Une quantité manquante ne fournit aucune comparaison déterminée de ce type à inverser.
Combiner inconnu avec un autre test
| Combinaison | Résultat |
|---|---|
| Inconnu AND faux | Faux |
| Inconnu AND vrai | Inconnu |
| Inconnu AND inconnu | Inconnu |
| Inconnu OR vrai | Vrai |
| Inconnu OR faux | Inconnu |
| Inconnu OR inconnu | Inconnu |
Bookshelf coûte 120,00. Dans stock > 10 OR price > 100, la condition sur le prix est vraie. OR n’exige qu’une partie vraie : la ligne est donc conservée même si la comparaison du stock est inconnue. Dans stock > 10 AND price > 100, la condition sur le stock reste indéterminée : le résultat est donc inconnu et la ligne est exclue.
Inclure volontairement les valeurs manquantes
SELECT first_name
FROM employees
WHERE department <> 'Sales'
OR department IS NULL;
Cette requête renvoie Ben, David, Farid, Hugo et Grace. La comparaison seule en renverrait quatre et exclurait Grace. La branche IS NULL inclut explicitement le personnel sans service attribué. L’inclusion ou non de ces personnes dans « hors de Sales » dépend de la réponse attendue ; la requête doit exprimer ce choix.
Une valeur NULL dans une liste NOT IN peut bloquer tout le résultat. department NOT IN ('Sales', NULL) signifie que le service doit différer de Sales et différer de NULL. Cette dernière comparaison est inconnue pour chaque ligne : la condition complète n’est donc jamais vraie. IN conserve néanmoins les correspondances réelles : department IN ('Sales', NULL) sélectionne les trois employés de Sales, mais ne trouve pas Grace.
Une valeur testée manquante produit aussi inconnu pour LIKE et pour une plage BETWEEN ordinaire. IS NULL et IS NOT NULL donnent des réponses déterminées pour ces colonnes scalaires. Vérifie séparément les valeurs manquantes avec ces tests lorsqu’un nombre de lignes te surprend.
Savoir quand les NULL sont regroupés
NULL = NULL reste inconnu ; on ne sait pas si deux numéros de téléphone manquants sont identiques. DISTINCT traite toutefois les valeurs manquantes répétées comme des doublons et ORDER BY les place ensemble. Pour une comparaison qui traite volontairement deux NULL comme égaux, SQLite et PostgreSQL proposent aussi IS NOT DISTINCT FROM.
Points clés
- WHERE conserve les lignes dont la condition est vraie et exclut celles dont elle est fausse ou inconnue.
- NOT laisse inconnu inchangé ; les filtres inversés peuvent encore exclure les lignes contenant NULL.
- Une branche OR vraie peut conserver une ligne dont une autre branche est inconnue.
- Ajoute explicitement IS NULL lorsque les valeurs manquantes doivent figurer dans la réponse.
- Un NULL dans une liste NOT IN empêche toute ligne de satisfaire ce filtre d’exclusion.
- La suppression des doublons regroupe les NULL, même si l’égalité ordinaire entre NULL est inconnue.
5Trier les résultats et choisir une page
Une limite de lignes ne prend un sens qu’une fois que tu as décidé quelles lignes doivent apparaître en premier. Le tri peut ordonner des nombres, du texte ou des dates, et les colonnes de tri suivantes départagent les lignes à égalité sur les précédentes. Les valeurs manquantes et les ex aequo demandent de l’attention lorsqu’une courte liste ou une page doit être reproductible. Tu construiras des ordres de tri totaux, appliqueras des limites après le filtrage et reconnaîtras les différentes syntaxes de limitation des lignes utilisées par les systèmes de bases de données courants.
5.1 Ordre croissant et ordre décroissant
ORDER BY définit l’ordre des lignes du résultat. Sans lui, SQL ne garantit pas quelle ligne apparaît en premier, même lorsqu’une petite table semble toujours renvoyer le même ordre.
Choisir le sens
| Sens | Nombres | Dates complètes | Texte |
|---|---|---|---|
ASC | Du plus petit au plus grand | De la plus ancienne à la plus récente | Ordre de la collation |
DESC | Du plus grand au plus petit | De la plus récente à la plus ancienne | Ordre inverse de la collation |
ASC est le sens par défaut. ORDER BY salary et ORDER BY salary ASC demandent le même sens. « Le salaire le plus élevé d’abord » appelle ORDER BY salary DESC.
SELECT first_name, salary
FROM employees
ORDER BY salary DESC;
Lis le résultat du plus élevé au plus bas : Farid 83 000, Ben 71 000, Emma 65 000, David 60 000, Hugo 58 000, Ana 52 000, Chloe 48 000 et Grace 45 000. La base de données réordonne les lignes du résultat ; cette requête ne modifie pas la table stockée.
Filtrer avant de trier
SELECT name, price
FROM products
WHERE category = 'Lighting'
ORDER BY price;
Seules les trois lignes de Lighting entrent dans ce résultat. Leurs prix croissants donnent Lamp Shade 15,50, Desk Lamp 24,99, puis Floor Lamp 89,00. ORDER BY suit WHERE dans l’instruction. Inverser ces clauses provoque une erreur de syntaxe.
La colonne de tri n’a pas besoin d’être affichée. SELECT first_name FROM employees ORDER BY salary DESC; donne le même ordre des noms sans afficher les salaires. PostgreSQL limite cette possibilité en présence de DISTINCT : une requête DISTINCT doit sélectionner ses colonnes de tri.
Lire le type de données stocké
Les colonnes numériques sont triées selon la valeur des nombres. Les colonnes textuelles sont triées caractère par caractère selon leur collation. Les valeurs textuelles '10', '9' et '100' se classent dans l’ordre '10', '100', '9' selon l’ordre ordinaire des caractères. Ce n’est pas un classement numérique correct : vérifie donc le type de la colonne lorsque des montants semblent mal ordonnés.
Les valeurs de hire_date dans l’exemple sont des dates textuelles complètes de largeur fixe, avec l’année en premier. ORDER BY hire_date commence par Farid le 2017-09-12 et se termine par Grace le 2024-02-19. DESC inverse cet ordre pour placer les dernières personnes embauchées en premier. Les dates textuelles commençant par le mois, comme MM/DD/YYYY, sont comparées par mois avant l’année et ne permettent pas d’obtenir un ordre chronologique fiable sur plusieurs années.
L’ordre du texte dépend de la collation
La collation binaire par défaut de SQLite place les lettres ASCII majuscules avant les minuscules. Selon cette règle, 'Zebra' précède 'apple' et 'é' vient après 'z'. De nombreuses bases PostgreSQL utilisent des collations qui tiennent compte de la langue et produisent un autre ordre. Une casse cohérente aide, mais les règles de comparaison de la base déterminent toujours l’ordre des caractères accentués et des autres caractères.
Utilise les noms de colonnes pour préciser clairement le tri. ORDER BY 2 DESC désigne le deuxième élément de la liste SELECT : déplacer des colonnes peut donc modifier le tri sans avertissement. ORDER BY 'salary' désigne une constante textuelle, pas la colonne des salaires : SQLite n’en tire aucun ordre utile et PostgreSQL le refuse. Écris ORDER BY salary.
Points clés
- ORDER BY détermine l’ordre des lignes ; ASC est le sens par défaut et DESC inverse le sens.
- WHERE filtre les lignes avant leur tri.
- La valeur des nombres, la représentation des dates et la collation du texte déterminent le sens de « croissant ».
- Nomme explicitement les colonnes de tri pour éviter les constantes entre apostrophes et les changements de rang des colonnes.
5.2 Plusieurs colonnes de tri, ex aequo et valeurs manquantes
Une deuxième colonne de tri ne compte que lorsque des lignes sont à égalité sur la première. Pense à une liste de personnel triée : regroupe d’abord par ville, puis classe les noms dans chaque ville.
Suivre les colonnes de tri de gauche à droite
SELECT last_name, city
FROM employees
ORDER BY city, last_name;
Le résultat commence par Kim et Okafor à Boston. Viennent ensuite Haddad, Lopez, Nguyen et O'Neill à Chicago. Brown et Carter à Denver sont en dernier. last_name ne concurrence pas city ; il ne détermine l’ordre qu’au sein d’une même ville.
Inverser les colonnes change l’ordre principal. ORDER BY last_name, city trie principalement par nom de famille et ne consulte la ville qu’en cas de noms identiques. Utilise une seule clause ORDER BY avec des virgules entre ses colonnes de tri. Une deuxième clause ORDER BY est invalide.
Donner son sens à chaque colonne
ORDER BY department, salary DESC signifie que les services sont triés par ordre croissant, puis les salaires par ordre décroissant dans chaque service. DESC ne s’applique qu’au salaire. Pour trier les deux par ordre décroissant, écris department DESC, salary DESC.
Avec l’ordre par défaut des NULL dans SQLite, la première forme place d’abord le service manquant de Grace. IT suit avec Farid puis Ben ; Marketing contient David puis Hugo ; Sales contient Emma, Ana, puis Chloe. Tu lis une hiérarchie de comparaisons : il ne s’agit pas de trier d’abord toutes les lignes par salaire puis d’ignorer cet ordre.
Départager les ex aequo avec une valeur unique
Les lignes égales sur toutes les colonnes de tri peuvent apparaître dans n’importe quel ordre. ORDER BY city ne détermine pas quel employé de Chicago vient en premier. Un ordre de tri total ajoute une dernière colonne qui identifie chaque ligne de manière unique :
SELECT first_name, city
FROM employees
ORDER BY city, employee_id;
Les identifiants départagent tous les employés d’une même ville. Pour des données inchangées, cela permet à un LIMIT ou à une page de sélectionner une partie reproductible de la liste ordonnée. Un critère de départage unique fixe les lignes qui apparaissent à la limite ; il n’ajoute pas les autres lignes ex aequo.
Placer volontairement les valeurs manquantes
Les valeurs par défaut diffèrent selon les bases de données :
| Base de données | NULL en ordre ASC | NULL en ordre DESC |
|---|---|---|
| SQLite, MySQL, SQL Server | Au début | À la fin |
| PostgreSQL, Oracle | À la fin | Au début |
La requête sur les services place donc Grace en dernier dans PostgreSQL avec son réglage par défaut, même si elle la place en premier dans SQLite. Cette différence est indépendante du sens de tri du salaire.
SELECT first_name, department, salary
FROM employees
ORDER BY department NULLS LAST, salary DESC;
SQLite 3.30 ou ultérieur, PostgreSQL et Oracle prennent en charge NULLS FIRST et NULLS LAST. Ici, ils placent Grace après tous les services enregistrés tout en conservant l’ordre des salaires dans chaque service. MySQL et SQL Server n’acceptent pas ces clauses.
Traduis la hiérarchie demandée dans l’ordre où elle est énoncée : « par service, avec le salaire le plus élevé d’abord dans chaque service » donne department, salary DESC. « Par ordre alphabétique du nom, puis du prénom » donne last_name, first_name. Ajoute un identifiant en dernier lorsque tu as besoin d’un ordre reproductible entre des personnes ayant les mêmes nom et prénom.
Points clés
- Les colonnes ORDER BY suivantes départagent les lignes à égalité sur les précédentes.
- ASC ou DESC s’applique à sa propre colonne ; un sens omis vaut ASC par défaut.
- Ajouter une dernière colonne de tri unique rend l’ordre total pour des données inchangées.
- La place des NULL dépend de la base de données ; les clauses NULLS FIRST et NULLS LAST la fixent explicitement lorsqu’elles sont prises en charge.
- Un critère de départage fixe le choix des lignes sans étendre LIMIT à tous les ex aequo.
5.3 Premiers résultats et pages avec LIMIT
LIMIT conserve au plus un nombre choisi de lignes de résultat. Il ne détermine pas quelles lignes méritent de figurer en premier. Utilise ORDER BY pour donner un sens à une courte liste, comme les mieux payés, les plus récents ou les moins chers.
Trier, puis limiter
SELECT first_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;
Les salaires triés commencent par Farid 83 000, Ben 71 000 et Emma 65 000 : ces trois lignes sont donc conservées. Sans ORDER BY, LIMIT 3 renvoie trois lignes quelconques, sans garantir qu’il s’agit des personnes les mieux payées.
WHERE agit avant la limite. WHERE city = 'Boston' ORDER BY salary DESC LIMIT 5 ne renvoie que David et Grace, car seuls deux employés satisfont la condition. LIMIT fixe un maximum : il ne demande pas d’inventer des lignes supplémentaires. LIMIT 0 n’en renvoie aucune.
Sauter des lignes pour une page ultérieure
OFFSET saute des lignes avant que LIMIT ne compte les lignes à renvoyer. ORDER BY salary DESC LIMIT 3 OFFSET 3 saute Farid, Ben et Emma, puis renvoie David, Hugo et Ana : les lignes de rangs quatre à six.
Pour la page k avec n lignes par page, saute (k − 1) × n lignes. La page trois avec trois lignes par page utilise LIMIT 3 OFFSET 6. Seuls Chloe et Grace restent. La première page utilise un décalage de zéro, pas de un.
« Deuxième ligne » et « deuxième valeur différente » sont deux demandes distinctes. ORDER BY salary DESC LIMIT 1 OFFSET 1 renvoie ici Ben avec 71 000. Si deux employés partageaient le salaire le plus élevé, cette requête renverrait une autre personne au salaire le plus élevé. Pour trouver le deuxième salaire différent, sélectionne DISTINCT salary avant de trier et de sauter des lignes.
Départager à la limite
ORDER BY city LIMIT 3 inclut les deux employés de Boston et un employé de Chicago, sans préciser lequel. ORDER BY city, employee_id LIMIT 3 sélectionne David, Grace et Ana. L’identifiant unique départage les lignes à la limite.
Pour conserver toutes les lignes à égalité sur la dernière valeur de tri, PostgreSQL 13 ou ultérieur et Oracle prennent en charge FETCH FIRST 3 ROWS WITH TIES. Avec ORDER BY city, cette clause conserve six lignes : les deux lignes de Boston et les quatre de Chicago. Si ORDER BY inclut aussi un identifiant unique, les lignes ne peuvent pas être à égalité sur la clé de tri complète.
Reconnaître la syntaxe de la base de données
| Base de données | Une limite de trois lignes |
|---|---|
| SQLite, PostgreSQL, MySQL | ORDER BY salary DESC LIMIT 3 |
| PostgreSQL, Oracle 12c ou ultérieur | ORDER BY salary DESC FETCH FIRST 3 ROWS ONLY |
| SQL Server | SELECT TOP (3) first_name, salary FROM employees ORDER BY salary DESC; |
SQL standard utilise OFFSET et FETCH, pas LIMIT. PostgreSQL et Oracle acceptent OFFSET 3 ROWS FETCH FIRST 3 ROWS ONLY. SQL Server utilise ORDER BY salary DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY ; ORDER BY est obligatoire pour cette forme de pagination.
SQLite et MySQL acceptent aussi LIMIT 6, 3, avec le décalage en premier. Préfère LIMIT 3 OFFSET 6 pour rendre les rôles explicites. La pagination réexécute une requête pour chaque page. Un ordre de tri total maintient la cohérence des pages tant que les données restent inchangées ; des insertions ou des suppressions entre les requêtes peuvent néanmoins faire répéter ou sauter des enregistrements.
Points clés
- ORDER BY détermine les premières lignes ; LIMIT conserve au plus le nombre demandé.
- OFFSET saute des lignes avant que LIMIT ne compte ; la première page utilise un décalage de zéro.
- Sélectionne d’abord DISTINCT lorsque tu classes des valeurs différentes plutôt que des lignes individuelles.
- Un critère de départage unique fixe le choix à la limite ; WITH TIES peut inclure des lignes supplémentaires à égalité sur la clé de tri complète.
- LIMIT, TOP et OFFSET/FETCH sont des formes de limitation des lignes propres à différentes bases de données.
- Des données modifiées peuvent déplacer les limites des pages entre les requêtes.
6Construire et vérifier une requête complète
Une question professionnelle combine généralement plusieurs choix : quels enregistrements comptent, quels détails afficher et quelles lignes viennent en premier. Préparer ces choix séparément t’aide à écrire une requête dont les parties concordent. L’ordre d’écriture des clauses et leur ordre logique expliquent pourquoi un filtre peut utiliser une colonne masquée et pourquoi une limite s’applique aux lignes retenues. Tu vérifieras aussi les bornes, les données manquantes et les ex aequo avant de te fier à un résultat qui paraît plausible.
6.1 Ordre d’écriture et traitement logique
Les clauses SQL s’écrivent dans un ordre fixe. Leur ordre logique explique le résultat comme une succession de décisions, même lorsque la base de données utilise un plan d’exécution interne différent.
Écrire l’instruction dans l’ordre des clauses
SELECT DISTINCT city
FROM employees
WHERE department = 'Sales'
ORDER BY city
LIMIT 2 OFFSET 0;
SELECT et FROM indiquent les colonnes demandées et la table source. Les autres clauses sont facultatives, mais lorsqu’elles sont présentes, elles conservent cet ordre : WHERE, ORDER BY, LIMIT, puis OFFSET dans cette forme avec LIMIT. DISTINCT se place immédiatement après SELECT.
Utilise une seule clause WHERE avec plusieurs conditions reliées entre elles. Un deuxième WHERE provoque une erreur de syntaxe. Il en va de même pour ORDER BY : place plusieurs colonnes de tri dans une seule clause, séparées par des virgules. Déplacer WHERE sous ORDER BY ne demande pas un ordre de traitement différent : cela produit du SQL invalide.
Suivre les décisions logiques
| Étape logique | Ce qui se passe dans l’exemple |
|---|---|
| FROM | Lire les lignes des employés. |
| WHERE | Conserver Ana, Chloe et Emma dans Sales. |
| SELECT | Conserver leurs villes : Chicago, Chicago, Denver. |
| DISTINCT | Réduire ces valeurs à Chicago et Denver. |
| ORDER BY | Placer Chicago avant Denver. |
| OFFSET et LIMIT | Ne sauter aucune ligne et en renvoyer au plus deux. |
Le résultat est Chicago, puis Denver. La ville répétée disparaît avant que la limite ne compte les lignes de résultat. La requête ne prend pas deux employés pour ensuite chercher s’ils vivent dans des villes différentes.
L’optimiseur peut utiliser un plan d’exécution physique différent qui produit le même résultat que cette séquence logique.
Utiliser les colonnes lorsqu’elles sont disponibles
WHERE teste les lignes sources avant que SELECT ne choisisse les colonnes affichées :
SELECT first_name
FROM employees
WHERE salary > 60000;
Cela fonctionne sans afficher le salaire. Les noms retenus sont Ben, Emma et Farid. Le salaire est toujours une colonne de chaque ligne source lorsque le test est effectué.
De même, filtrer avant de limiter est essentiel pour obtenir le premier résultat au sein d’un groupe :
SELECT first_name
FROM employees
WHERE department = 'Sales'
ORDER BY salary DESC
LIMIT 1;
La réponse est Emma. Le personnel de Sales est d’abord retenu ; les salaires de ses membres sont ensuite classés. Prendre d’abord la personne la mieux payée de l’entreprise puis vérifier si cette seule ligne appartient à Sales manquerait la réponse attendue, car Farid appartient à IT.
Rendre la structure visible
Écris une clause par ligne et place les conditions plus longues sur des lignes distinctes en retrait. Pour « les produits de Furniture à moins de 200 dollars, du prix le plus élevé au plus bas », utilise :
SELECT name, price
FROM products
WHERE category = 'Furniture'
AND price < 200
ORDER BY price DESC;
Office Chair à 149,00 vient avant Bookshelf à 120,00. Les deux conditions partagent un seul WHERE, le seuil numérique n’a pas de symbole monétaire et ORDER BY trie les lignes retenues. Vérifier chaque ligne selon son rôle permet de repérer plus facilement les erreurs de syntaxe comme les mauvaises interprétations.
Points clés
- Écris SELECT, FROM, WHERE, ORDER BY et LIMIT dans l’ordre requis des clauses.
- Logiquement, lis la table, filtre, sélectionne les colonnes, supprime les doublons, trie, puis limite les lignes.
- WHERE peut tester des colonnes sources que SELECT n’affiche pas.
- Filtrer avant de classer permet de trouver le premier résultat dans le groupe demandé.
6.2 D’une demande à une réponse vérifiée
Avant d’écrire du SQL, repère les décisions distinctes que contient une demande courante. Chaque décision correspond à une clause, et chaque clause peut être vérifiée par rapport à la réponse attendue.
Prendre six décisions
- Quelle table contient les enregistrements ? Choisis FROM.
- Quels enregistrements sont retenus ? Construis WHERE.
- Quels champs répondent à la question ? Choisis SELECT.
- Les valeurs répétées du résultat sont-elles utiles ? Décide s’il faut DISTINCT.
- Qu’est-ce qui doit venir en premier ? Construis ORDER BY.
- Y a-t-il un maximum ou une page ? Ajoute LIMIT et OFFSET.
Pour « au moins », inclus l’égalité. « L’un de » suggère IN, « contient » suggère un motif LIKE avec des signes pourcentage aux deux extrémités, « manquant » suggère IS NULL et « valeurs différentes » suggère DISTINCT. Une demande portant sur les n premiers nécessite à la fois un sens de tri et une limite.
Construire une courte liste de personnel
« Affiche les noms et les dates d’embauche des trois dernières personnes embauchées hors de Sales qui ont un numéro de téléphone enregistré, de la plus récente à la plus ancienne. » Inclus le personnel sans service attribué dans le sens donné ici à « hors de Sales ».
Commence par employees. La règle sur le service des personnes retenues est department <> 'Sales' OR department IS NULL. Regroupe ce choix pour que la règle sur le téléphone s’applique aux deux branches. Affiche les noms et les dates, puis classe les lignes retenues :
SELECT first_name, last_name, hire_date
FROM employees
WHERE (department <> 'Sales' OR department IS NULL)
AND phone IS NOT NULL
ORDER BY hire_date DESC
LIMIT 3;
Grace Okafor, embauchée le 2024-02-19, est première ; David Kim, embauché le 2020-11-23, deuxième ; et Farid Haddad, embauché le 2017-09-12, troisième. Supprimer la branche IS NULL exclut Grace et ne laisse que deux résultats. Si une demande manque de clarté, décide comment compter les services manquants et indique ton choix avec la réponse.
Combiner catégorie, prix et stock
« Quels produits de Lighting ou de Storage coûtent moins de 20 dollars américains et sont en stock, du moins cher au plus cher ? » Utilise IN pour les deux choix de catégorie et exige une quantité connue positive :
SELECT name, price
FROM products
WHERE category IN ('Lighting', 'Storage')
AND price < 20
AND stock > 0
ORDER BY price;
Paper Tray à 9,99 vient avant Desk Organizer à 18,75. Lamp Shade est assez bon marché et appartient à une catégorie choisie, mais son stock est nul : il ne satisfait donc pas le dernier test. Une quantité en stock manquante ne satisferait pas non plus le test, car elle ne permet pas d’établir que le stock est positif.
Vérifier les lignes qui pourraient révéler une erreur
Commence par SELECT * FROM products LIMIT 5; pour explorer le schéma et quelques enregistrements. Ajoute les filtres un à un, en vérifiant les changements du nombre de lignes dans le résultat et en affichant temporairement les colonnes testées lorsque c’est utile.
Teste les bornes exactes, les valeurs manquantes, la casse du texte et les ex aequo à la limite. NOT montre les lignes pour lesquelles une condition était fausse ; il ne révèle pas celles pour lesquelles elle était inconnue. Exécute séparément des tests IS NULL. Vérifie que le résultat contient les colonnes demandées et que ORDER BY départage les ex aequo qui influent sur la réponse.
Lorsque tu transfères la requête vers une autre base de données, vérifie la syntaxe de limitation des lignes, les règles de casse de l’égalité et de LIKE, la délimitation des noms, le traitement des dates et la place des NULL. Les exemples utilisent LIMIT dans SQLite et PostgreSQL ; la forme de limitation des lignes de SQL standard utilise OFFSET avec FETCH FIRST.
Points clés
- Prévois séparément la table, les lignes retenues, les colonnes affichées, les doublons, l’ordre et le nombre de lignes.
- Exprime explicitement le choix concernant les valeurs manquantes lorsqu’une exclusion doit inclure les enregistrements non attribués.
- Vérifie les bornes et l’effet de chaque filtre par rapport à la question.
- Examine les NULL séparément, car NOT ne transforme pas inconnu en vrai.
- Vérifie à nouveau la casse, les dates, les noms, l’ordre des NULL et les limites de lignes lorsque tu changes de base de données.
Requêtes SELECT en SQL : exemples
1Des enregistrements des employés à une liste de villes
11 étapes
- 1IntroductionUne table, deux types de réponses
Une liste du personnel et une liste des villes du personnel utilisent les mêmes enregistrements d’employés, mais nécessitent des résultats de formes différentes. Un SELECT simple choisit les champs à afficher. DISTINCT peut ensuite réduire les répétitions des valeurs sélectionnées. Nous allons d’abord construire un résultat à deux colonnes sur les employés, puis poser une question sur les villes différentes et voir ce qui disparaît.
- 2ExplicationChoisir les colonnes affichées
Commence par une demande précise : affiche la ville de chaque employé suivie de son prénom. Écris :
SELECT city, first_name FROM employees;La liste SELECT fixe l’ordre des colonnes du résultat : la ville vient donc en premier. FROM fournit la table. Il n’y a pas de filtre, donc les huit employés fournissent chacun une ligne ; cette requête simple laisse les enregistrements stockés inchangés.
- 3ExempleLire la forme du résultat
L’enregistrement d’Ana fournit Chicago et Ana ; celui de Ben fournit Denver et Ben. Chaque autre employé fournit les deux mêmes champs. Le résultat comporte donc huit lignes et deux colonnes. Les villes répétées restent présentes, car ces lignes décrivent toujours des personnes différentes. Aucun ORDER BY n’est présent : ces exemples désignent donc les lignes sans promettre d’ordre d’affichage.
- 4DéfiVérifier une liste SELECT modifiée
Que change la requête si elle devient
SELECT first_name FROM employees;? Indique son nombre de lignes et son nombre de colonnes.---reveal---
Elle renvoie toujours huit lignes, avec désormais une colonne, first_name. Retirer la ville de SELECT supprime un champ affiché, pas des enregistrements d’employés. Un filtre ou une limite de lignes serait nécessaire pour réduire le nombre de lignes.
- 5ConseilRepérer les erreurs de syntaxe
Sépare les noms de colonnes par des virgules, mais ne mets pas de virgule finale avant FROM. Utilise un point-virgule pour terminer l’instruction ;
--commence un commentaire qui se poursuit jusqu’à la fin de la ligne. Si la base de données signale une colonne inconnue, compare son orthographe avec le schéma.SELECT *est utile pour un premier aperçu, tandis que des noms explicites permettent de cibler un résultat enregistré. - 6ExplicationDemander les villes différentes
Demande maintenant dans quelles villes se trouve le personnel. Les prénoms n’ont plus leur place dans cette réponse :
SELECT DISTINCT city FROM employees;Les huit entrées de ville se réduisent à Chicago, Denver et Boston, sans ordre garanti. DISTINCT supprime les répétitions du résultat sélectionné, pas de la table stockée des employés. Chaque ville apparaît une fois, même si plusieurs personnes peuvent y vivre.
- 7ExempleComparer les lignes sélectionnées complètes
Ajoute le service à la liste SELECT. Ana et Chloe fournissent toutes deux la paire Sales-Chicago, qui se réduit à une ligne. Emma fournit Sales-Denver, qui reste présente, car la ville est différente. Le résultat complet de
SELECT DISTINCT department, city FROM employees;comporte sept lignes. DISTINCT s’écrit une fois après SELECT et compare tous les champs sélectionnés ensemble. - 8DéfiUn identifiant unique modifie la suppression des doublons
Combien de lignes
SELECT DISTINCT employee_id, city FROM employees;renverrait-il, et pourquoi ?---reveal---
Les huit lignes restent présentes. Chaque employee_id est unique : chaque paire identifiant-ville diffère donc de toutes les autres. La répétition des villes ne suffit pas à rendre les lignes sélectionnées complètes identiques.
- 9Point cléDéterminer ce qu’indique une ligne NULL
Une liste DISTINCT des services contient Sales, IT, Marketing et une ligne NULL pour Grace. Des marqueurs manquants répétés seraient eux aussi réduits à un seul. Cette ligne indique qu’un service n’est pas enregistré ; ce n’est pas un autre service nommé. Le regroupement des doublons traite les NULL ensemble, même si une comparaison ordinaire
NULL = NULLest inconnue. - 10DéfiTerminer par une courte liste triée
Prévois le résultat de
SELECT DISTINCT city FROM employees ORDER BY city LIMIT 2;. Donne les valeurs dans l’ordre où elles sont renvoyées et explique ce que la limite compte.---reveal---
Boston, puis Chicago. DISTINCT réduit d’abord les valeurs de ville à trois ; ORDER BY trie ces valeurs et LIMIT en conserve deux. Il compte les villes différentes du résultat après suppression des doublons, pas deux enregistrements d’employés.
- 11RécapitulatifAdapter le résultat à la question
Un résultat sur le personnel conserve les champs d’identification ; une liste de villes sélectionne la ville seule avec DISTINCT. Les colonnes sélectionnées déterminent les comparaisons de doublons, tandis que ORDER BY détermine l’ordre des lignes. Lorsque tu modifies une requête, vérifie à la fois les champs affichés et ce que représente une ligne du résultat.
2Construire un filtre qui exprime ce que tu veux
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionChaque filtre pose une question précise
- 2ExplicationTraduire le seuil de salaire
- 3DéfiInclure la borne si nécessaire
- 4ConseilÉcrire simplement les littéraux numériques
- 5ExplicationMettre une valeur textuelle entre apostrophes
- 6ExempleConserver une apostrophe dans la valeur
- 7ExplicationUtiliser une date complète comme borne
- 8DéfiVérifier une date avec une heure
- 9ExplicationRelier les conditions
- 10ExempleAppliquer une même règle de ville aux possibilités
- 11DéfiInverser le groupe
- 12DéfiCombiner une date et un groupe de services
- 13RécapitulatifExaminer une ligne révélatrice
3Choisir une liste exacte, une plage ou un motif
15 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionTrois sens de la correspondance
- 2ExplicationCommencer par des choix de catégories entières
- 3ExempleAppliquer une règle de stock à la liste
- 4DéfiPrévoir une exclusion
- 5ExplicationPlacer un prix dans une plage
- 6DéfiExclure volontairement les bornes
- 7ConseilCouvrir un mois entier avec des heures
- 8ExplicationDéterminer où placer le fragment
- 9ExempleCompter un caractère avec un tiret bas
- 10ExempleRendre le caractère générique littéral
- 11DéfiVérifier les extrémités d’un motif
- 12LienVérifier le traitement de la casse par la base de données
- 13DéfiTenir compte d’un téléphone manquant
- 14DéfiCombiner les trois types de correspondance
- 15RécapitulatifChoisir la forme selon le sens
4Trouver les données manquantes et raisonner à leur sujet
10 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionUne quantité non enregistrée reste indéterminée
- 2ExempleDistinguer zéro d’une valeur manquante
- 3ExplicationTester directement la présence
- 4DéfiVérifier la chaîne vide
- 5ExplicationSuivre une comparaison et son contraire
- 6ExempleLaisser une branche OR vraie décider
- 7DéfiUne branche AND fausse peut trancher
- 8Point cléÉviter NULL dans une liste d’exclusion
- 9DéfiInclure les services manquants et exiger un téléphone
- 10RécapitulatifExaminer séparément les données manquantes
5Construire une page triée reproductible
15 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionUne page est une partie d’une réponse ordonnée
- 2ExemplePlacer les valeurs les plus élevées en premier
- 3DéfiTrier uniquement les produits retenus
- 4ConseilSavoir si le tri est numérique
- 5ExplicationLire les priorités de tri à partir de la gauche
- 6DéfiDonner son sens à chaque colonne de tri
- 7ExplicationDépartager les ex aequo restants
- 8LienPlacer explicitement les valeurs manquantes
- 9ExempleConserver les trois premières lignes classées
- 10ExemplePasser après la première page
- 11Point cléLe rang d’une ligne diffère du rang d’une valeur distincte
- 12DéfiExaminer les ex aequo à la limite
- 13ConseilReconnaître une autre forme de limitation des lignes
- 14DéfiConserver la deuxième page de villes
- 15RécapitulatifDéfinir le classement avant de prélever une partie
6Traduire et vérifier une demande professionnelle
12 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionSéparer les décisions d’une demande
- 2ExplicationÉcrire les clauses dans un ordre valide
- 3ExempleSuivre le modèle logique
- 4DéfiFiltrer avant de choisir le premier
- 5ExplicationCerner la demande sur le personnel
- 6ExempleRendre explicite la règle sur le service
- 7ExempleAppliquer l’exigence sur le téléphone
- 8ExempleClasser les enregistrements retenus
- 9DéfiVérifier le choix concernant les valeurs manquantes
- 10DéfiRelier les clauses dans une même chaîne de traitement
- 11ConseilChoisir des vérifications qui révèlent les erreurs
- 12RécapitulatifRelire la réponse à la lumière de la demande
Requêtes SELECT en SQL : QCM
Série 1 : Listes, plages et motifs de caractères10 Questions Pratiques
Question 1 sur 10
fee contient les valeurs 12, 18, 24 et 30. Quelles valeurs satisfont WHERE fee BETWEEN 18 AND 30 ?Afficher la réponseMasquer la réponse
Question 2 sur 10
report ?Afficher la réponseMasquer la réponse
Question 3 sur 10
requests contient les lignes (request_id, region) (31, 'South'), (32, 'East'), (33, 'South'). Quel ensemble d’identifiants satisfait WHERE region IN ('South', 'South') ?Afficher la réponseMasquer la réponse
Question 4 sur 10
labels, quel ensemble de valeurs correspond à label LIKE '__7%' parmi 'AB7', 'A7', 'AB70' et 'ABC7' ?Afficher la réponseMasquer la réponse
Question 5 sur 10
temperature contient 4, 9, 14, 19 et NULL. Quelles valeurs satisfont WHERE temperature NOT BETWEEN 9 AND 14 ?Afficher la réponseMasquer la réponse
Question 6 sur 10
promo_code contient 'VIP_2', 'VIPA2', 'VIP_' et 'VIP2'. Quel ensemble correspond à WHERE promo_code LIKE 'VIP!_%' ESCAPE '!' ?Afficher la réponseMasquer la réponse
Question 7 sur 10
appointments stocke du texte contenant une heure au format de largeur fixe YYYY-MM-DD HH:MM:SS. Quelle condition sélectionne tous les rendez-vous de février 2028 ?Afficher la réponseMasquer la réponse
Question 8 sur 10
word LIKE 'map%' parmi 'Maple', 'map', 'roadmap' et 'MAPS' ?Afficher la réponseMasquer la réponse
Question 9 sur 10
members contient les lignes (member_id, tier) (41, 'Gold'), (42, 'Silver'), (43, NULL). Quel ensemble d’identifiants satisfait WHERE tier IN ('Silver', NULL) ?Afficher la réponseMasquer la réponse
Question 10 sur 10
shipments enregistre un port par ligne. Quelle condition exclut à la fois Oakland et Tacoma lorsque toutes les valeurs de port sont enregistrées ?Afficher la réponseMasquer la réponse
Série 2 : Colonnes, comparaisons et conditions claires10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
rooms comporte 12 lignes. Quelle est la forme du résultat de SELECT floor, room_name FROM rooms; ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
parcels stocke une valeur numérique weight_kg. Quelle condition conserve les colis pesant au plus 8 kilogrammes ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
D'Arcy dans une colonne surname ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
tickets contient status et une valeur numérique priority. Quelle condition sélectionne les tickets ouverts ou en attente, ayant chacun une priorité d’au moins 4 ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
visits contient les paires (site, day) ('East', 'Mon'), ('East', 'Mon'), ('East', 'Tue') et ('West', 'Mon'). Combien de lignes SELECT DISTINCT site, day FROM visits; renvoie-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
team = 'Blue', city = 'Austin' et score = 62. Satisfait-elle WHERE team = 'Blue' OR city = 'Miami' AND score >= 80, et pourquoi ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
YYYY-MM-DD. Quelle condition sélectionne les dates postérieures à l’année civile 2025 ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
zone est North ou West ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
loans contient les valeurs numériques days_late 0, 2, 5 et NULL. Combien de lignes satisfont WHERE days_late <> 0 ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
stockrooms contient les lignes (room_id, building) (1, 'C'), (2, 'A'), (3, 'A'), (4, 'B'), (5, 'C'). Quelles valeurs ordonnées résultent de SELECT DISTINCT building FROM stockrooms ORDER BY building DESC LIMIT 2; ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Valeurs manquantes et filtres combinés10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
contacts stocke les valeurs phone NULL, '', 'NULL' et '555-0188'. Combien de lignes satisfont WHERE phone IS NULL ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
devices contient battery_pct = NULL et status = 'ready'. Que se passe-t-il avec WHERE battery_pct > 50 OR status = 'ready' ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
email est enregistrée, y compris une chaîne vide si elle est stockée comme valeur dans PostgreSQL ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
jobs contient les lignes (job_id, hours, urgent) (51, NULL, 'yes'), (52, 6, 'no'), (53, 2, 'yes'), (54, NULL, 'no'). Quel ensemble satisfait WHERE NOT (hours > 4) OR urgent = 'yes' ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
files contient les valeurs folder 'Archive', 'Active' et NULL. Quelle condition inclut Active et le dossier manquant, tout en excluant Archive ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
routes contient les lignes (route_id, depot) (61, 'A'), (62, 'B'), (63, NULL). Quel ensemble d’identifiants satisfait WHERE depot NOT IN ('A', NULL) OR depot IS NULL ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
load : 0, 3, 7, NULL, NULL. Deux requêtes utilisent WHERE load > 3 et WHERE NOT (load > 3). Quels sont leurs nombres de lignes, dans cet ordre ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
deliveries contient les valeurs district 'Hill', NULL, 'Hill', NULL et 'Lake'. Combien de lignes SELECT DISTINCT district FROM deliveries; renvoie-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
WHERE rating >= 4, puis vérifie les lignes exclues avec WHERE NOT (rating >= 4). Certains enregistrements n’apparaissent dans aucun des deux résultats. Quel test supplémentaire révèle les enregistrements dont la note n’a pas été enregistrée ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
messages contient les objets 'Note A', 'Alert', NULL et 'Note B'. Combien de lignes satisfont WHERE subject NOT LIKE 'Note%' ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Classement, ex aequo et pages suivantes10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
duration_minutes contient les valeurs 16, 4 et 23. Dans quel ordre apparaissent-elles avec ORDER BY duration_minutes ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
racers contient les lignes (racer_id, group_name, points) (71, 'A', 8), (72, 'B', 12), (73, 'A', 15). Quel ordre des identifiants résulte de ORDER BY group_name, points DESC ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
orders fixe possède des valeurs order_id uniques et plusieurs lignes partagent à la fois order_date et total. Quel ORDER BY place les dates les plus récentes en premier, les totaux les plus élevés d’une même date en premier et donne un ordre total ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
offers contient les lignes (offer_id, rate) (81, 40), (82, 40), (83, 35), (84, 30). Quel taux résulte de SELECT DISTINCT rate FROM offers ORDER BY rate DESC LIMIT 1 OFFSET 1; ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
queues contient les noms 'Delta', NULL et 'Alpha'. Avec ORDER BY queue_name ASC par défaut, où se trouve la ligne NULL dans SQLite et PostgreSQL ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
sales contient les lignes (sale_id, amount) (91, 70), (92, 70), (93, 55), (94, 55), (95, 20). Dans PostgreSQL, combien de lignes SELECT sale_id, amount FROM sales ORDER BY amount DESC FETCH FIRST 3 ROWS WITH TIES; renvoie-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
'6', '12' et '100' avec une collation binaire. Quel est leur ordre croissant ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
ORDER BY item_id LIMIT 4 OFFSET 4 sur des lignes inchangées dont les identifiants uniques vont de 1 à 12. Avant la requête de la page suivante, la ligne 2 est supprimée. Quels identifiants LIMIT 4 OFFSET 8 renvoie-t-il maintenant avec le même tri ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
tasks contient les lignes (task_id, owner, hours) (101, 'Lee', 9), (102, 'Ari', 8), (103, 'Lee', 5), (104, 'Lee', 3). Quel identifiant résulte de SELECT task_id FROM tasks WHERE owner = 'Lee' ORDER BY hours DESC LIMIT 1 OFFSET 1; ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 5 : Requêtes complètes et vérification des résultats10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
courses contient title, une valeur numérique fee et une valeur numérique places_left. Quelle requête affiche les titres et les tarifs des cours à moins de 75 € avec des places disponibles, du moins cher au plus cher ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
cases contient les lignes (case_id, team, opened_on, phone) (111, 'Red', '2026-06-12', 'x'), (112, NULL, '2026-06-20', 'y'), (113, 'Blue', '2026-06-18', NULL), (114, 'Blue', '2026-06-10', 'z'). Quels identifiants ordonnés correspondent aux deux dossiers les plus récents hors de Red, en incluant les équipes non attribuées, avec un téléphone enregistré ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
rentals contient branch = 'East' et returned = 'yes'. Une requête doit afficher les locations non rendues de East ou de West, mais cette ligne apparaît. Le filtre est branch = 'East' OR branch = 'West' AND returned = 'no'. Quelle correction applique la règle de retour aux deux agences ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
catalog contient des noms de produits en ASCII. Quelle condition trouve les noms contenant steel sans tenir compte des différences de casse ASCII dans SQLite et PostgreSQL ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
'G', 'G1', 'H2', 'J' et 'J1' avec une collation binaire. Quel ensemble satisfait WHERE code BETWEEN 'G' AND 'J' AND code NOT LIKE 'H%' ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
logs contient les lignes (region, channel) ('East', 'web'), ('East', 'web'), ('East', 'store'), ('West', 'web'), ('West', 'store'). Quelles lignes ordonnées résultent de SELECT DISTINCT region, channel FROM logs WHERE channel = 'web' ORDER BY region DESC LIMIT 1; ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
bids contient les lignes (bid_id, amount) (121, 90), (122, 90), (123, 80), (124, 80). Combien de lignes SELECT bid_id, amount FROM bids ORDER BY amount DESC, bid_id FETCH FIRST 3 ROWS WITH TIES; renvoie-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
sensors contient les lignes (sensor_id, reading, enabled) (131, NULL, 'yes'), (132, 8, 'yes'), (133, 2, 'no'), (134, NULL, 'no'). Quel ensemble satisfait WHERE NOT (reading > 5 AND enabled = 'yes') ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
fee > 50, et les seuls enregistrements de test disponibles ont des tarifs de 20 et 80. Quel tarif de test supplémentaire révèle le plus directement l’erreur ?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
A
AND
ASC
price ASC place le produit d’éclairage le moins cher en premier et le plus cher en dernier.B
BETWEEN
price BETWEEN 15.50 AND 89.00 inclut les produits dont le prix est exactement de 15,50 ou de 89,00, les deux bornes indiquées.Borne
BETWEEN 15.50 AND 89.00 est inclus : les produits coûtant exactement 15,50 ou 89,00 sont donc tous deux retenus.Borne inférieure
price BETWEEN 89.00 AND 15.50 dépasse la borne supérieure : aucune valeur ne correspond donc.C
Caractère générique pourcentage
'Lamp%' autorise n’importe quel suffixe après Lamp, y compris aucun suffixe pour la valeur Lamp.Caractère générique tiret bas
Chaîne vide
phone = '' recherche une chaîne vide et ne trouve pas les valeurs de téléphone manquantes des employés.Clause ESCAPE
LIKE 'SPRING!_%' ESCAPE '!' fait du tiret bas après SPRING un caractère littéral.Clause FROM
SELECT name, price FROM products; indique que products est la source des deux champs.Clause SELECT
SELECT city, first_name FROM employees; place la ville avant le prénom de l’employé.Clause WHERE
WHERE salary < 50000 conserve les employés payés moins de 50 000, même lorsque le résultat masque leurs salaires.Collation
'Chicago' de 'chicago' : un filtre sur 'chicago' manque donc les lignes stockées sous Chicago.Colonne de tri
Colonne de tri principale
ORDER BY city, last_name : les noms de Boston restent avant ceux de Chicago.Combinaison sélectionnée
Commentaire SQL
-- peut expliquer pourquoi un filtre inclut le personnel sans service attribué, sans modifier ses conditions.Construction progressive d’une requête
Critère de départage
D
DESC
ORDER BY hire_date DESC place un employé embauché en 2024 avant un employé embauché en 2023 dans la liste du personnel.Dialecte SQL
DISTINCT
SELECT DISTINCT city FROM employees; ne liste que ces trois villes.F
Forme ISO des dates
hire_date >= '2023-01-01' inclut les employés embauchés à cette date ou après dans les comparaisons chronologiques.I
Identifiant
hire_date nomme une colonne, tandis que le texte entre apostrophes '2024-02-19' représente une valeur.ILIKE
name ILIKE '%desk%' peut trouver des noms de produits contenant le texte Desk avec une majuscule.IN
department IN ('IT', 'Marketing') sélectionne tous les employés de IT ou de Marketing sans répéter une comparaison de service.IS NOT DISTINCT FROM
IS NOT NULL
phone IS NOT NULL conserve un employé dont le téléphone est enregistré, même si son service est manquant.IS NULL
phone IS NULL trouve les employés dont l’enregistrement ne contient aucune valeur de téléphone.J
Jeu de résultats
SELECT city FROM employees; comporte huit lignes et autorise les villes répétées.L
Ligne de résultat en double
LIKE
name LIKE '%Lamp%' trouve tous les noms de produits contenant Lamp, que Lamp apparaisse au début, au milieu ou à la fin.LIMIT
Liste IN
(6, 2, 2, 4) correspond aux mêmes enregistrements d’employés que (2, 4, 6), malgré son ordre et sa répétition.Littéral numérique
20.50 dans price < 20.50 ne comporte ni guillemets, ni séparateur de milliers, ni symbole monétaire.Littéral textuel
'O''Neill' correspond au nom O’Neill, car son apostrophe doublée représente une seule apostrophe.Logique à trois valeurs
price > 100 est vraie.N
NOT
stock > 10 n’inclut pas un produit dont le stock est manquant, car la condition reste inconnue pour cette ligne.NOT BETWEEN
stock NOT BETWEEN 5 AND 40 conserve un produit dont le stock est nul et un autre dont le stock est de soixante, mais exclut un stock manquant.NOT IN
city NOT IN ('Chicago', 'Denver') conserve le personnel de Boston, car sa ville diffère des deux éléments.NULL
NULLS LAST
department NULLS LAST place les employés sans service enregistré après les services enregistrés dans les requêtes SQLite et PostgreSQL actuelles.O
OFFSET
Opérateur de comparaison
>= inclut un employé payé exactement 60 000 dans salary >= 60000, car ce salaire est égal au seuil.Optimiseur de requêtes
OR
ORDER BY
ORDER BY salary DESC place l’employé le mieux payé en premier sans modifier aucun enregistrement stocké des employés.Ordre de tri total
ORDER BY city, employee_id fixe le rang de chaque employé grâce à l’identifiant unique.Ordre des clauses
Ordre logique de traitement
P
Page
Plage de dates semi-ouverte
'2024-04-01', ce qui conserve les heures tardives du dernier jour.Priorité des opérateurs
R
Requête
SELECT first_name FROM employees; demande à la base de données le champ du prénom de chaque employé.S
Seuil inclus
salary >= 60000.T
TOP
SELECT TOP (3) peut remplacer une courte liste limitée à trois lignes avec LIMIT lorsque la requête est écrite pour SQL Server.Type DATE
DATE '2022-01-01' ; SQLite n’utilise pas cette syntaxe de littéral typé.V
Valeur de vérité inconnue
stock > 10 : cette ligne ne satisfait donc pas le filtre.Vérification aux limites
Vérification du résultat
W
WITH TIES
- 1Modèle relationnel
- 2Requêtes SELECT en SQL
- 3Colonnes calculées SQL
- 4Fonctions d’agrégation SQL
- 5Jointures SQL
- 6Créer des tables SQL
À propos de cette unité
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.