Skip to Content

Terrain 8 — SQLite

9 drills · ~12 min · Chapitres liés : Partie 8 (écrivez le SQL sur papier !)

1. Écrivez la requête : le record (meilleur score) du thème ‘symfony’.

SELECT MAX(score) AS best FROM sessions WHERE theme = ?

(Toujours paramétré — jamais de concaténation.)

2. Écrivez : les 20 dernières sessions, plus récentes d’abord.

SELECT * FROM sessions ORDER BY played_at DESC LIMIT 20

(Servi par l’index (theme, played_at DESC) si filtré par thème.)

3. Le taux de réussite global d’un thème — avec les DEUX pièges de la division.

SELECT CAST(SUM(correct_count) AS REAL) / NULLIF(SUM(total), 0) FROM sessions WHERE theme = ?

CAST (sinon division entière → 0) + NULLIF (sinon division par zéro sur table vide).

4. Les 10 questions les plus ratées (min 3 tentatives) — l’astuce du AVG sur 0/1 ?

SELECT question_id, COUNT(*) AS attempts, 1.0 - AVG(correct) AS failRate FROM answers GROUP BY question_id HAVING attempts >= 3 ORDER BY failRate DESC LIMIT 10

AVG(correct) sur des 0/1 = le taux de réussite direct.

5. Enregistrer une session + ses réponses : quelle structure de code, et pourquoi ?

withTransactionAsync — atomique : jamais de session sans ses answers après un crash au milieu. (Et lastInsertRowId du runAsync pour lier les answers.)

6. Le pattern de migrations du cours en 3 éléments ?

PRAGMA user_version (la version de la base) + un tableau ordonné de migrations + chaque migration en transaction avec incrément du PRAGMA. On n’édite JAMAIS une migration livrée.

7. Quel PRAGMA oublié rend les ON DELETE CASCADE décoratifs ?

PRAGMA foreign_keys = ONpar connexion, à chaque ouverture (dans migrate/onInit).

8. Ajouter une colonne response_ms sans casser les données existantes ?

Nouvelle migration : ALTER TABLE answers ADD COLUMN response_ms INTEGER NOT NULL DEFAULT 0 — les lignes existantes prennent 0 (« inconnu »), les nouvelles la vraie valeur.

9. Les stats locales avec TanStack Query : staleTime, et le déclencheur de rafraîchissement ?

staleTime: Infinity (rien ne les change sauf nous) + invalidateQueries({ queryKey: ['stats'] }) dans le onSuccess de la mutation d’enregistrement.


👉 Terrain suivant : 9 — APIs natives