Mini-cours de SQLite

Partie III

Ouvrons la base de données, zipCodesBelges.db, téléchargeable ici, et apprendrons à poser des questions à toute base de données.

Structure de la table provinces :

CREATE TABLE provinces(
id_province  INTEGER PRIMARY KEY,
nomProvince  TEXT UNIQUE);

Structure de la table localites :

CREATE TABLE localites(
id_localite  INTEGER PRIMARY KEY,
nomLocalite  TEXT NOT NULL,
CP           TEXT NOT NULL,
num_province INTEGER,
FOREIGN KEY(num_province) REFERENCES provinces(id_province)
);

SQL : SELECT ... FROM ... ;

Syntaxe complète pour sélectionner :

Dans le cadre de ce mini-cours, nous n'aborderons que l'essentiel.

L'instruction SELECT ... FROM ... ; est la septième et dernière instruction SQL majeure. C'est l'instruction la plus utilisée, car elle nous donnera les réponses.

SELECT est le premier mot de toute requête.

Une requête est une demande, une question posée à la base de données.

SELECT n'est pas une instruction pour afficher, mais bien pour sélectionner. Toutefois, ce programme, sqlite.exe, affiche le contenu de la mémoire. D'autres programmes, comme ceux que vous créerez bientôt, conservent ce contenu dans une variable.

*

Cette instruction permet de sélectionner toutes les colonnes.

Pour sélectionner toutes les colonnes de la table localites, sans condition de restriction sur le nombre d'enregistrements, = sélectionner toutes les colonnes et tous les enregistrements, = sélectionner tout :
SELECT * FROM localites;

Les 2823 lignes ne sont pas reprises sur cette page.

Pour afficher tout le contenu de la table provinces :
SELECT * FROM provinces;

0|
1|Anvers
2|Brabant Flamand
3|Brabant Wallon
4|Bruxelles (19 communes)
5|Flandre-Occidentale
6|Flandre-Orientale
7|Hainaut
8|Liège
9|Limbourg
10|Luxembourg
11|Namur

En réalité, en Belgique, il n'existe que 10 provinces. Bruxelles (19 communes) n'est pas une province.

WHERE

La clause WHERE permet de restreindre le nombre d'enregistrements à sélectionner. Cette clause est unique et est toujours placée après le FROM. Ce qui suit la clause WHERE sont la ou les conditions auxquelles les enregistrements sélectionnés doivent correspondre.

Pour sélectionner les enregistrements en fonction d'une valeur dans une colonne :
SELECT * FROM nom_table WHERE nom_colonne = ... ;

Pour sélectionner toutes les données de l'enregistrement ayant 1637 dans la colonne id_localite.
SELECT * FROM localites WHERE id_localite=1637;

1637|MONS|7000|7

id_localite est une colonne spéciale. Elle a comme attribut INTEGER PRIMARY KEY. Cela signifie qu'elle ne contiendra que des nombres entiers uniques. La requête ci-dessus ne sélectionnera qu'un seul enregistrement ou aucun ( si 1637 n'existe pas )

Pour sélectionner toutes les données de l'enregistrement ayant ANVERS dans la colonne nomLocalite.
SELECT * FROM localites WHERE nomLocalite="ANVERS";


Aucune réponse n'est affichée (  car ANVERS n'existe pas dans la colonne nomLocalite )
Lorsque la valeur recherchée est une chaîne de caractères, elle est mise entre guillemets.

Toutefois, si la question est :
SELECT * FROM localites WHERE nomLocalite="ANTWERPEN";

61|ANTWERPEN|2000|1
62|ANTWERPEN|2018|1
63|ANTWERPEN|2020|1
64|ANTWERPEN|2030|1
65|ANTWERPEN|2040|1
66|ANTWERPEN|2050|1
67|ANTWERPEN|2060|1

Pour connaître le nombre de codes postaux attribués à la ville ANTWERPEN :
SELECT COUNT(*) FROM localites WHERE nomLocalite="ANTWERPEN";

7

Pour connaître le nombre de codes postaux dans la province du Hainaut :
SELECT COUNT(*) FROM localites WHERE num_province=7;

468

Pour sélectionner les enregistrements correspondant au code postal 7334 :
SELECT * FROM localites WHERE CP="7334";

986|Hautrage|7334|7
2531|Villerot|7334|7

Le code postal n'est pas un nombre, mais une chaîne de caractères même si elle n'est composée que de chiffres.

Limiter le nombre de colonnes

Pour limiter le nombre de colonnes à sélectionner, il suffit de remplacer * par le nom des colonnes et séparer ces noms par une virgule.

Pour sélectionner que le code postal et nom des localités correspondant au code postal 7334 :
SELECT CP,nomLocalite FROM localites WHERE CP="7334";

7334|Hautrage
7334|Villerot

L'ordre des colonnes dans la requête peut être différent de celui donné dans la structure de la table.

Pour sélectionner que le code postal et nom des localités correspondant à la province 0 :
SELECT CP,nomLocalite FROM localites WHERE num_province=0;

7510|3 Suisses
2099|Antwerpen x
1007|Assemblée de la Commission Communautaire Française
1005|Assemblée Réunie de la Commission Communautaire
1931|Brucargo
1099|Bruxelles X
1804|Cargovil
1008|Chambre des Représentants
6099|Charleroi X
1935|Corporate Village
2075|CSM Antwerpen X
6075|CSM Charleroi X
9075|CSM Gent X
4075|CSM Liege X
1046|European External Action Service
9099|Gent X
1733|HighCo DATA
1041|International Press Center
5589|Jemelle
4099|Liège X
1035|Ministère de la Région de Bruxelles Capitale
1934|Office Exchange Brussels Airport Remailing
1031|Organisations Sociales Chrétiennes
1110|OTAN
1012|Parlement de la Communauté française
1047|Parlement Européen
5012|Parlement Wallon
1100|Postcheque
1006|Raad van de Vlaamse Gemeenschapscommissie
1044|RTBF
1033|RTL-TVI
5010|SA SudPresse
0612|Saint-Nicolas
1101|Scanning
1009|Senat de Belgique
7010|SHAPE
1105|SOC
1212|SPF Mobilité
1049|Union Européenne - Commission
1048|Union Européenne - Conseil
7511|Vitrine Magique
1011|Vlaams parlement
1043|VRT
1818|VTM
7512|Yves Rocher
7513|Yves Rocher

On constate qu'il s'agit non pas de localité mais d'organisations. Mais, on constate surtout que la colonne nomLocalite est triée, sans avoir utilisé la clause ORDER BY que nous verrons bientôt, car les données ont été enregistrées dans l'ordre alphabétique des noms de localités.

DISTINCT

Le mot-clé DISTINCT impose de ne retenir que les valeurs distinctes. Ce mot-clé est placé immédiatement avant FROM.

SELECT DISTINCT nomLocalite FROM localites WHERE nomLocalite<="ANTZ";

'S Gravenwezel
'S Herenelderen
3 Suisses
AALST
AALTER
AARSCHOT
AARTSELAAR
AFFLIGEM
AISEAU-PRESLES
ALKEN
ALVERINGEM
AMAY
AMBLÈVE
ANDENNE
ANDERLECHT
ANDERLUES
ANHÉE
ANS
ANTHISNES
ANTOING
ANTWERPEN

nomLocalite<="ANTZ", on se souviendra du codage des caractères

Pour connaître le nombre de localités ayant un nom distinct et inférieur à "ANTZ".
SELECT count(DISTINCT nomLocalite) FROM localites WHERE nomLocalite<"ANTZ";

21

Pour connaître le nombre de localités ayant un nom inférieur à "ANTZ".
SELECT count(nomLocalite) FROM localites WHERE nomLocalite<"ANTZ";

27

ORDER BY

La clause ORDER BY permet de trier les résultats sur la colonne indiquée. Cette clause est unique et placée avant la clause LIMIT ( si elle existe ).

Pour sélectionner que les codes postaux et noms des organisations ayant un code postal et trier cette liste sur base du code postal :
SELECT CP,nomLocalite FROM localites WHERE num_province=0 ORDER BY CP;

Par défaut, l'ordre est croissant. Pour obtenir l'ordre décroissant, il faut ajouter, après le nom de la colonne, DESC. Le tri peut être fait sur plusieurs colonnes. ( cas rare ). Le tri est alors d'abord fait sur la première colonne à trier, puis si la première colonne contient des données identiques, le tri se fait sur la deuxième colonne.

0612|Saint-Nicolas
1005|Assemblée Réunie de la Commission Communautaire
1006|Raad van de Vlaamse Gemeenschapscommissie
1007|Assemblée de la Commission Communautaire Française
1008|Chambre des Représentants
1009|Senat de Belgique
1011|Vlaams parlement
1012|Parlement de la Communauté française
1031|Organisations Sociales Chrétiennes
1033|RTL-TVI
1035|Ministère de la Région de Bruxelles Capitale
1041|International Press Center
1043|VRT
1044|RTBF
1046|European External Action Service
1047|Parlement Européen
1048|Union Européenne - Conseil
1049|Union Européenne - Commission
1099|Bruxelles X
1100|Postcheque
1101|Scanning
1105|SOC
1110|OTAN
1212|SPF Mobilité
1733|HighCo DATA
1804|Cargovil
1818|VTM
1931|Brucargo
1934|Office Exchange Brussels Airport Remailing
1935|Corporate Village
2075|CSM Antwerpen X
2099|Antwerpen x
4075|CSM Liege X
4099|Liège X
5010|SA SudPresse
5012|Parlement Wallon
5589|Jemelle
6075|CSM Charleroi X
6099|Charleroi X
7010|SHAPE
7510|3 Suisses
7511|Vitrine Magique
7512|Yves Rocher
7513|Yves Rocher
9075|CSM Gent X
9099|Gent X

Le code postal pour Saint-Nicolas, saint patron des écoliers, est le 0612.

LIMIT

La clause LIMIT permet de limiter aux n premiers enregistrements de la liste.

La même liste limitée aux 5 premiers enregistrements de la liste triée dans l'ordre croissant des codes postaux :
SELECT CP,nomLocalite FROM localites WHERE num_province=0 ORDER BY CP LIMIT 5;

0612|Saint-Nicolas
1005|Assemblée Réunie de la Commission Communautaire
1006|Raad van de Vlaamse Gemeenschapscommissie
1007|Assemblée de la Commission Communautaire Française
1008|Chambre des Représentants

La même liste limitée aux 5 premiers enregistrements de la liste triée dans l'ordre décroissant des codes postaux :
SELECT CP,nomLocalite FROM localites WHERE num_province=0 ORDER BY CP DESC LIMIT 5;

9099|Gent X
9075|CSM Gent X
7513|Yves Rocher
7512|Yves Rocher
7511|Vitrine Magique

Le nom de la clause peut changer d'un gestionnaire de base de données à l'autre.

Expression

literal-value bind-parameter schema-name . table-name . column-name unary-operator expr expr binary-operator expr function-name ( DISTINCT expr ) filter-clause over-clause , * ( expr ) , CAST ( expr AS type-name ) expr COLLATE collation-name expr NOT LIKE GLOB REGEXP MATCH expr expr ESCAPE expr expr ISNULL NOTNULL NOT NULL expr IS NOT expr expr NOT BETWEEN expr AND expr expr NOT IN ( select-stmt ) expr , schema-name . table-function ( expr ) table-name , NOT EXISTS ( select-stmt ) CASE expr WHEN expr THEN expr ELSE expr END raise-function
Source : expression

= , ==

... WHERE num_province=0 ...

... WHERE num_province==0 ...

<> , !=

... WHERE num_province!=0 ...

... WHERE num_province<>0 ...

AND

La clause WHERE est unique, mais on peut ajouter des conditions via AND et OR

Pour sélectionner les enregistrements en fonction de valeurs dans deux colonnes  :
SELECT * FROM nom_table WHERE nom_colonne1 = ... AND nom_colonne2 = ... ;

La même liste avec comme condition supplémentaire que le code postal soit inférieur à 2000  :
SELECT CP,nomLocalite FROM localites WHERE num_province=0 AND CP<"2000" ORDER BY CP;

0612|Saint-Nicolas
1005|Assemblée Réunie de la Commission Communautaire
1006|Raad van de Vlaamse Gemeenschapscommissie
1007|Assemblée de la Commission Communautaire Française
1008|Chambre des Représentants
1009|Senat de Belgique
1011|Vlaams parlement
1012|Parlement de la Communauté française
1031|Organisations Sociales Chrétiennes
1033|RTL-TVI
1035|Ministère de la Région de Bruxelles Capitale
1041|International Press Center
1043|VRT
1044|RTBF
1046|European External Action Service
1047|Parlement Européen
1048|Union Européenne - Conseil
1049|Union Européenne - Commission
1099|Bruxelles X
1100|Postcheque
1101|Scanning
1105|SOC
1110|OTAN
1212|SPF Mobilité
1733|HighCo DATA
1804|Cargovil
1818|VTM
1931|Brucargo
1934|Office Exchange Brussels Airport Remailing
1935|Corporate Village

La même liste avec encore une condition supplémentaire, que le code postal soit supérieur à 1499 :
SELECT CP,nomLocalite FROM localites WHERE num_province=0 AND CP<"2000" AND CP>"1499" ORDER BY CP;

1733|HighCo DATA
1804|Cargovil
1818|VTM
1931|Brucargo
1934|Office Exchange Brussels Airport Remailing
1935|Corporate Village

OR

Le mot OR permet d'ajouter des lignes dans le résultat.

La même liste auquel on ajoute les enregistrements qui répondent à la condition suivante : code postal soit supérieur 5999.
SELECT CP,nomLocalite FROM localites WHERE (num_province=0 AND CP<"2000" AND CP>"1499") OR (num_province=0 AND CP>"5999") ORDER BY CP;

Les parenthèses peuvent être utilisées pour réunir plusieurs conditions.

1733|HighCo DATA
1804|Cargovil
1818|VTM
1931|Brucargo
1934|Office Exchange Brussels Airport Remailing
1935|Corporate Village
6075|CSM Charleroi X
6099|Charleroi X
7010|SHAPE
7510|3 Suisses
7511|Vitrine Magique
7512|Yves Rocher
7513|Yves Rocher
9075|CSM Gent X
9099|Gent X

On constate que la liste est triée sur le code postal et que les codes postaux sont bien compris entre 1500 et 2000 ou supérieurs à 5999. On constate aussi que la requête SELECT s'allonge au fur et à mesure de l'augmentation de nos desiderata.

LIKE

Avec la clause LIKE, on peut comparer une donnée à un modèle.

Le caractère % permet de dire vaut zéro, un ou plusieurs caractères.
Le caractère _ permet de dire un seul caractère quelconque.

Exemples de modèles de toute chaîne de caractères :

Pour obtenir la liste des localités dont le nom contient "aut"
SELECT nomLocalite FROM localites WHERE nomLocalite LIKE "%aut%";

Assemblée de la Commission Communautaire Française
Assemblée Réunie de la Commission Communautaire
Autelbas
Autre-Eglise
Autreppe
BRUNEHAUT
Erbaut
FEXHE-LE-HAUT-CLOCHER
Flémalle-Haute
Haut-Fays
Haut-Ittre
Haut-Le-Wastia
Hautrage
LEUZE-EN-HAINAUT
Mont-Gauthier
Parlement de la Communauté française
Rochehaut
Sautin
Sautour
Wauthier-Braine

Pour obtenir la liste des localités dont le nom se termine par "aut"
SELECT nomLocalite FROM localites WHERE nomLocalite LIKE "%aut";

BRUNEHAUT
Erbaut
LEUZE-EN-HAINAUT
Rochehaut

Pour obtenir la liste des localités dont le nom débute par "saint"
SELECT nomLocalite,CP,num_province FROM localites WHERE nomLocalite LIKE "saint%";

Saint-Amand|6221|7
Saint-André|4606|8
Saint-Aubin|5620|11
Saint-Denis|7034|7
Saint-Denis-Bovesse|5081|11
SAINT-GEORGES-SUR-MEUSE|4470|8
Saint-Gérard|5640|11
Saint-Germain|5310|11
Saint-Géry|1450|3
SAINT-GHISLAIN|7330|7
SAINT-GILLES|1060|4
SAINT-HUBERT|6870|10
Saint-Jean-Geest|1370|3
SAINT-JOSSE-TEN-NOODE|1210|4
Saint-Léger|7730|7
SAINT-LÉGER|6747|10
Saint-Marc|5003|11
Saint-Mard|6762|10
Saint-Martin|5190|11
Saint-Maur|7500|7
Saint-Médard|6887|10
SAINT-NICOLAS|4420|8
Saint-Nicolas|0612|0
Saint-Pierre|6800|10
Saint-Remy|6460|7
Saint-Remy|4672|8
Saint-Remy-Geest|1370|3
Saint-Sauveur|7912|7
Saint-Servais|5002|11
Saint-Séverin|4550|8
Saint-Symphorien|7030|7
Saint-Vaast|7100|7
Saint-Vincent|6730|10
SAINT-VITH|4780|8
Sainte-Cécile|6820|10
Sainte-Marie-Chevigny|6800|10
Sainte-Marie-Sur-Semois|6740|10
SAINTE-ODE|6680|10
Saintes|1480|3

On constate deux Saint-Remy dans deux provinces différentes.

Pour obtenir la liste des localités dont le nom débute par "ha" et se terminant par "t"
SELECT nomLocalite FROM localites WHERE nomLocalite LIKE "ha%t";

HAACHT
HAALTERT
Haccourt
Haillot
Hamont
HANNUT
Hanret
Hargimont
Harnoncourt
HASSELT
Hauset

Pour obtenir la liste des localités dont le nom débute par "s" suivi de trois lettres quelconques se terminant par "mont"
SELECT nomLocalite FROM localites WHERE nomLocalite LIKE "s___mont";

SPRIMONT
STOUMONT

IS NULL

L'opérateur IS NULL permet de sélectionner les enregistrements n'ayant pas de données dans la colonne visée.

Pas de donnée ne signifie pas zéro dans une colonne de type numérique ou un ou plusieurs espaces dans une colonne de type texte. Pas de donnée signifie case vide dans la grille.

Pour sélectionner les lignes ayant des " trous " dans une colonne.
SELECT * FROM nom_table WHERE nom_colonne IS NULL;

Pour sélectionner les lignes ayant des " trous " dans la colonne nomLocalite.
SELECT * FROM localites WHERE nomLocalite IS NULL;


Aucune réponse car aucun enregistrement ne répond à cette condition.

Pour connaître le nombre de " trous " dans la colonne nomLocalite.
SELECT COUNT(*) FROM localites WHERE nomLocalite IS NULL;

0

IS NOT NULL

L'opérateur IS NOT NULL permet permet de sélectionner les enregistrements ayant des données non nulles dans la colonne visée.

Pour connaître le nombre de " non-trous " dans la colonne nomLocalite.
SELECT COUNT(*) FROM localites WHERE nomLocalite IS NOT NULL;

2823

IN

L'opérateur IN permet de choisir parmi plusieurs valeurs.

Pour sélectionner les lignes dont les données de la colonne choisie sont dans un ensemble de valeurs.
SELECT * FROM nom_table WHERE nom_colonne IN (valeur1, valeur2, ...);

Pour sélectionner les lignes ayant des " trous " dans la colonne nomLocalite.
SELECT * FROM localites WHERE id_localite IN (724, 1000, 3);

3|3 Suisses|7510|0
724|FLÉMALLE|4400|8
1000|Heindonk|2830|1

Les lignes semblent être triées sur la colonne id_localite. En réalité, dans la table les enregistrements ont été stockés dans l'ordre du id_localite.

BETWEEN

L'opérateur BETWEEN permet de choisir entre 2 valeurs comprises.

Pour sélectionner les lignes dont les données de la colonne choisie sont entre deux valeurs.
SELECT * FROM nom_table WHERE nom_colonne BETWEEN valeur1 AND valeur2;

Pour sélectionner les lignes dont les données de la colonne id_localite sont comprises entre 1000 et 1003 compris nomLocalite.
SELECT * FROM localites WHERE id_localite BETWEEN 1000 AND 1003;

1000|Heindonk|2830|1
1001|Heinsch|6700|10
1002|Heist-Aan-Zee|8301|5
1003|HEIST-OP-DEN-BERG|2220|1

NOT

Exemples :

SELECT id_fiche FROM fiches WHERE num_fard = 18 AND numPosition > 44 AND numPosition NOT IN (163,162,161,157,155,154,140,138,118,115,113,112);

DELETE FROM fiches WHERE num_fard = 18 AND numPosition > 44 AND numPosition NOT IN (163,162,161,157,155,154,140,138,118,115,113,112);

Les fonctions

Le nom des fonctions peut être écrit en minuscule.

COUNT(*)

Cette fonction sert à compter le nombre d'enregistrements.

Pour compter le nombre d'enregistrements d'une table.
SELECT count(*) FROM nom_table;

Pour compter le nombre d'enregistrements de la table localites.
SELECT count(*) FROM localites;

2823

Pour compter le nombre d'enregistrements de la table provinces.
SELECT COUNT(id_province) FROM provinces;

12

MIN()

La fonction MIN(nom_colonne) permet d'obtenir la plus petite des données de la colonne de la liste des enregistrements sélectionnés.

SELECT MIN(nom_colonne) FROM nom_table;

Pour obtenir la plus petite des données contenues dans la colonne id_province de la table provinces.
SELECT MIN(id_province) FROM provinces;

0

MAX()

La fonction MAX(nom_colonne) permet d'obtenir la plus grande des données de la colonne de la liste des enregistrements sélectionnés.

SELECT MAX(nom_colonne) FROM nom_table;

Pour obtenir la plus grande des données contenues dans la colonne nomProvince de la table provinces.
SELECT MAX(nomProvince) FROM provinces;

Namur

Les fonctions MIN() et MAX() peuvent aussi s'appliquer à des chaînes de caractères.

SUM()

La fonction SUM(nom_colonne) permet d'obtenir la somme des données numériques non nulles de la colonne de la liste des enregistrements sélectionnés.

SELECT SUM(nom_colonne) FROM nom_table;

Pour obtenir la somme des données contenues dans la colonne id_province de la table provinces.
SELECT SUM(id_province) FROM provinces;

66

Cette somme ne présente aucun intérêt. Par contre, si la colonne représentait les montants dus par des clients ...

AVG()

La fonction AVG(nom_colonne) permet d'obtenir la moyenne des données numériques non nulles de la colonne de la liste des enregistrements sélectionnés.

SELECT AVG(nom_colonne) FROM nom_table;

Pour obtenir la moyenne des données contenues dans la colonne id_province de la table provinces.
SELECT AVG(id_province) FROM provinces;

5.5

SQLite travaille avec le point décimal et non la virgule décimale

Cette somme ne présente aucun intérêt. Par contre, si la colonne représentait les points obtenus en français ...

REPLACE()

La fonction REPLACE() permet de remplace toutes les occurences d'une string par une autre string, dans un champ.

Exemple : Remplacer dans le champ 'description' de toutes les fiches, '@€' par '\n'

UPDATE fiches SET description=REPLACE(description,'@€','\n');

LENGTH()

La fonction LENGTH() permet de calculer le nombres de caractères d'une chaîne de caractères.

Pour sélectionner selon la longueur d'une chaîne de caractères d'une colonne.
SELECT * FROM nom_table WHERE LENGTH(nom_colonne)>n;

Pour sélectionner les noms de localités dont la longueur est supérieure à 25.
SELECT id_localite,nomLocalite FROM localites WHERE LENGTH(nomLocalite)>25;

92|Assemblée de la Commission Communautaire Française
93|Assemblée Réunie de la Commission Communautaire
441|Chastre-Villeroux-Blanmont
448|Chaussée-Notre-Dame-Louvignies
682|European External Action Service
796|Geest-Gérompont-Petit-Rosière
1152|International Press Center
1326|Lasne-Chapelle-Saint-Lambert
1487|Malèves-Sainte-Marie-Wastines
1612|Ministère de la Région de Bruxelles Capitale
1654|Montignies-Saint-Christophe
1759|Nil-Saint-Vincent-Saint-Martin
1800|Office Exchange Brussels Airport Remailing
1850|Ophain-Bois-Seigneur-Isaac
1869|Organisations Sociales Chrétiennes
1886|OTTIGNIES-LOUVAIN-LA-NEUVE
1916|Parlement de la Communauté française
2007|Raad van de Vlaamse Gemeenschapscommissie
2474|Union Européenne - Commission
2475|Union Européenne - Conseil

PRINTF()

La fonction PRINTF() permet d'afficher une chaîne de caractères comme on le ferait en C.

Exemple : voir la section "GROUP BY"

Autres fonctions utiles

SQL :  ... GROUP BY ...

Exemple :

SELECT "N° compte" AS compte, printf("%.2f", SUM("Montant")) AS somme, "Catégorie"
 FROM iban GROUP BY compte ORDER BY printf("%09.2f", somme);

SQL : ... INNER JOIN ... ON ...

Ci-dessous le type de jointure le plus courant. La jointure d'intersection entre deux tables.

Lors de la création de la table principale ( ici, localites ), elle a été liée à la table secondaire ( ici, provinces ). Ces deux tables sont alors joignables via INNER JOIN ... ON.

Dans la requête, il faut d'abord joindre les tables.
FROM table1 INNER JOIN table2 ou
FROM table2 INNER JOIN table1
L'ordre n'a pas d'importance.

Ensuite, il faut joindre les deux colonnes.
ON colonne_1=colonne_x ou
ON colonne_x=colonne_1
L'ordre n'a pas d'importance.

Pour éviter toute ambiguïté, le nom de la colonne doit toujours être précédé du nom de sa table suivi d'un point.
nom_table.nom_colonne

La clause INNER JOIN ... ON se place entre le FROM et le WHERE

SELECT localites.nomLocalite,provinces.nomProvince FROM (localites INNER JOIN provinces ON provinces.id_province=localites.num_province) WHERE nomLocalite LIKE "saint-R%";

Saint-Remy|Hainaut
Saint-Remy|Liège
Saint-Remy-Geest|Brabant Wallon

Toutefois, si le nom de toutes les colonnes est différent dans toute la base de données, il n'est pas d'ambiguïté. Dans ce cas, le nom des tables n'est pas nécessaire.

SELECT nomLocalite,nomProvince FROM (localites INNER JOIN provinces ON id_province=num_province) WHERE nomLocalite LIKE "saint-R%";

Saint-Remy|Hainaut
Saint-Remy|Liège
Saint-Remy-Geest|Brabant Wallon

Pour lier trois tables :

SELECT nomLocalite,nomProvince,nomPays FROM ((localites
INNER JOIN provinces ON id_province=num_province)
INNER JOIN pays ON id_pays=num_pays)
WHERE nomLocalite LIKE "saint-R%";

SQL : ... LEFT JOIN ... ON ...

Une SELF JOIN est une jointure qui concerne tous les enregistrements de la table de gauche (identifiée par le nom qui suit le mot-clé FROM)

Une RIGHT JOIN est une LEFT JOIN dont le nom de la table de gauche a été mis à droite ... (identifiée par le nom qui suit le mot-clé JOIN) et celui de droite à gauche. Une RIGHT JOIN est une LEFT JOIN où le nom des tables a été permuté.

SQL : SELF JOIN

Une SELF JOIN est une INNER ou LEFT jointure sur la table elle-même. Ce type de jointure est utilisée lorsque l'enregistrement stocke un lien de filiation avec un autre enregistrement.

Exemple de SELF JOIN :

 .schema groups
CREATE TABLE groups(id_group INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL UNIQUE,
num_group INTEGER DEFAULT 1,
FOREIGN KEY(num_group) REFERENCES groups(id_group));

Cette table contient l'ID du groupe, le nom du groupe et le numéro du groupe parent.
Ainsi, un groupe a un autre groupe comme parent (hormis le groupe ayant ID=1)

Pour afficher le nom de ce groupe parent, il faut faire une jointure sur la table elle-même, telle que

SELECT t1.id_group AS id_group, t1.nom AS nom, t2.nom AS filsDE FROM groups t1
 LEFT JOIN groups t2 ON t2.id_group = t1.num_group

Pour lever toute ambiguïté, le nom de chaque colonne utilisée DOIT être préfixé par l'alias du nom de sa table (suivi d'un point). Toutefois, ces colonnes préfixées peuvent ne pas avoir d'alias.

Pour info :

6 types de jointures