select
est probablement la plus utilisée du langage, et peut-être aussi la plus complexe. On se propose de commencer son étude par quelques exemples simples, avant de voir les cas les plus compliqués.
select
est la suivante.
Exemple 33. Forme simple de select
SELECT [DISTINCT] [nom_de_table.]nom_de_colonne | * | expression [AS alias_de_colonne], ... FROM nom_de_table [AS alias_de_table] [WHERE predicat] [ORDER BY nom_de_colonne [ASC | DESC], ...
select
est la liste des colonnes ou expressions que l'on souhaite voir afficher. Chaque élément de cette liste peut être préfixé par un nom de table s'il s'agit d'une colonne. Ce préfixage est obligatoire si deux colonnes de mêmes noms cohabitent dans cette liste, dans ce cas il est nécessaire de lever l'ambigüité.
Chaque nom de colonne ou expression peut être associé à un alias, de façon à rendre lisible l'affichage final.
Voyons quelques exemples :
Exemple 34. Colonnes et expressions dans une requête SELECT
select nom, prenom ... select max(ddnaissance)... select Marins.nom as nom_marin,
Exemple 35. Spécifications des tables dans une requête SELECT
select ... from Marins, Commune ... select max(ddnaissance)… select m1.nom, m2.nom from Marins as m1, Marin as m2 …
Nous verrons dans la suite qu'il est également possible de mettre une requête
select
dans la clause
from
. On appelle cela une requête imbriquéee.
select
n'est en général pas classé. Si l'on souhaite le classer par ordre alphabétique, ou numérique, il faut utiliser une clause
order by
. Cette clause peut prendre une liste de colonnes en paramètres.
Cette première requête classe les marins par
nom
, dans l'ordre croissant.
from
de cette requête. L'argument d'une clause
where
doit donc toujours se réduire à une expression dont le résultat ne peut prendre que deux valeurs :
true
ou
false
.
Tableau 8. Opérateurs de comparaison
Opérateur | Comparaison numérique | Comparaison textuelle | Comparaison temporelle |
---|---|---|---|
= | Égal | Égal | Même moment |
< | Plus petit | Avant | Plus tôt |
> | Plus grand | Après | Ensuite |
<= | Plus petit ou égal | Avant ou égal | Pas après |
>= | Plus grand ou égal | Après ou égal | Pas avant |
<> | Différent | Différent | Pas au même moment |
and
: et logique classique ;
or
: ou logique classique ;
not
: négation logique classique.
and
entre une valeur
true
et une valeur
null
? Ou encore, quel valeur nulle est-elle inférieure ou supérieure à 2 ? La réponse du SQL est spécifiée : elle est
unknown
.
unknown
.
Il n'existe qu'une seule manière de savoir si une valeur est nulle ou inconnue, c'est de la tester explicitement grâce au prédicat
is
, qui s'utilise comme dans les exemples suivants.
Ce premier exemple nous donne tous les marins dont on a oublié de renseigner le prénom.
is unknown
).
Exemple 39. Prédicat IS UNKNOWN
select nom, (ddmort > ddnaissance) as age_de_mort from Marins where (ddmort > ddnaissance) is unknown ;
is
avec
null
et
unknown
. C'est ce prédicat qu'il faut utiliser si l'on veut tester qu'une valeur vaut
true
ou
false
.
Il est très important de noter que
null
et
unknown
ne sont égaux à rien, pas même à eux-mêmes.
L'algèbre booléenne du SQL est donc un peu particulière, en ce sens qu'elle gère un troisième état en plus des habituels
true
et
false
:
unknown
. Toute opération booléenne avec
unknown
a pour résultat
unknown
.
like
est utilisé pour comparer les chaînes de caractères à l’aide de caractères de substitution. On compare une chaîne à un motif, dont les caractères
_
et
%
représentent respectivement n’importe quel caractère unique, et n’importe quelle suite de caractères, éventuellement de longueur nulle. L’utilisation du caractère
%
peut conduire à des recherches très longues, ce prédicat est donc à utiliser avec précaution.
Voyons quelques exemples simples. La requête suivante sélectionne tous les marins dont le nom commence M.
=
. Donc si
A = 'Bart'
et
B = 'Bart '
(notons les espaces en fin de chaîne), alors
(A = B)
renverra
true
, alors que
(A like B)
renverra
false
.
Si une comparaison de chaînes est tentée alors qu’une des deux chaînes vaut
null
, alors le résultat sera
unknown
.
between
permet de tester si une valeur se trouve entre deux autres valeurs. Voici un exemple d'utilisation.
true
si l'élément comparé est dans la liste en paramètre du
in
. Cette liste peut être explicite (comme sur notre exemple), ou peut être exprimée par une sous-requête. La négation de
in
ne renvoie par nécessairement le complément, c'est notamment le cas s'il se trouve des valeurs nulles.
exists
ne renvoie pas nécessairement le complément, du fait des valeurs nulles.
On peut vérifier la validité d’une jointure à l’aide de ce prédicat. Écrivons par exemple une requête qui teste que tous les champs de notre colonne
id_commune
ont bien une correspondance dans la table
Communes
:
Exemple 44. Prédicat EXISTS
select nom, prenom, id_commune from Marin where not exists ( select * from Commune, Marin where Commune.id = Marin.id_commune) ;
where
, dans ce cas la sélection a lieu sur le résultat de cette requête imbriquée ;
exists
ou
in
.
where
.
Exemple 45. Requête imbriquée dans une clause
where
select * from ( select Marins.nom as nom, Marins.prenom as prenom, Communes.nom as nom_commun from Marins join Communes on Marins.id_commune = Communes.id ) as marin_commune order by nom, prenom ;
as marin_commune
, et sa propre liste de champs, également définie par des alias. Cette table locale est aussi appelée
inline view
dans la documentation en anglais.
Une fois cette table locale créée, elle peut être utilisée exactement comme une table normale.
select
se complexifie alors un peu, et devient la suivante.
Exemple 46. Forme simple de select avec fonction d'agrégation
SELECT [DISTINCT] [nom_de_table.]nom_de_colonne | * | expression [AS alias_de_colonne], ... FROM nom_de_table [AS alias_de_table] [WHERE predicat] [GROUP BY liste_de_colonne_a_grouper] [HAVING condition_sur_les_groupes] [ORDER BY nom_de_colonne [ASC | DESC], ...
Tableau 9. Fonctions d'agrégations
Nom | Opération effectuée |
---|---|
AVG()
|
Calcule la moyenne de ses argument. |
COUNT()
|
Retourne le nombre d'arguments passés. |
MAX()
|
Retourne la plus grande valeur de ses arguments. |
MIN()
|
Retourne la plus petite valeur de ses arguments. |
SUM()
|
Retourne la somme des arguments. |
Marins
.
Exemple 49. Utilisation de AVG() ... GROUP BY
select nom_commune, avg(age) as age_moyen from Marins group by nom_commune ;
group by
indique au serveur SQL qu'il doit regrouper les marins par commune avant de calculer la moyenne d'âge de ces marins, groupe par groupe. Le résultat comportera donc autant de lignes qu'il y a de communes différentes dans la table Marins.
L'utilisation de la clause
having
permet de filtrer ce type de résultat. Dans l'exemple qui suit, on ne s'intéresse qu'aux communes pour lesquelles la moyenne d'âge est supérieure à 20 ans.
Exemple 50. Utilisation de AVG() ... GROUP BY ... HAVING
select nom_commune, avg(age) as age_moyen from Marins group by nom_commune having age_moyen > 20 ;
where
et la clause
having
. Dans ce type de requête, la clause
where
agit comme filtre sur les données avant l'application du regroupement des données. La clause
having
agit une fois les groupages effectués et les fonctions d'agrégation évaluées.