SQL - requêtesRequêtes sur une table

Créer des tables en bases de données est une chose, mais si vous ne savez pas les exploiter, ça ne sert pas à grand chose.

"Faut savoir, au chapitre précédent, vous nous dites que c'est bon, on a fait le principal, et là en fait non!"
C'est vrai, on a fait le plus important en terme de sauvegarde et stockage des données. On a une base bien calibrée et propre, et toutes les données qui sont insérées le sont proprement. Donc oui on a fait une bonne partie du travail. Maintenant il faut qu'on apprenne à utiliser et exploiter ces données.
Pour faire cela on utilise les requêtes SQL.

En SQL, on parle de requête SFW. Elle suit la syntaxe suivante:
SELECT .... FROM .... WHERE ....

Je ne l'ai pas dit, mais c'est l'occasion de le faire. En SQL, dans les mots de requêtage (select, insert, drop, ...), il n'y a pas de notion de casse, c'est-à-dire que l'on peut indifférement utiliser les majuscules ou les minuscules.
Donc on peut écrire SELECT * FROM table ou select * from table, c'est la même chose. Plutôt pratique pour ne pas se prendre la tête!

Donc voilà les trois termes importants d'une requête:
select: permet de coder la projection, donc d'afficher les colonnes à garder
from: permet de définir les tables qui vont être utilisées
where: permet de coder la sélection. Elle est optionnelle, mais on la garde souvent même sans conditions (on met alors where 1)

Le résultat d'une requête, comme en algèbre relationnelle, est une relation (ou une table) sur le schéma défini par la clause select. C'est donc un tableau avec une colonne par attribut.
A noter que l'on peut nommer une requête, cela s'appelle une vue. On verra dans un chapitre prochain à quoi ça correspond.

Reprenons notre tableau de gènes.
Nom et description des gènes du chromosome 1
En AR: πnom, descrchromosome=1(Gene))
En SQL: select nom, descr from Gene where chromosome=1;

La passerelle entre ensemble et multi-ensemble

En algèbre relationnelle, on parle d'ensemble de valeurs, en SQL on parle de multi-ensemble. La seule différence est qu'en SQL, il n'y aura pas de gestion de la redondance, principalement pour des histoires de coûts mémoire.
Il est cependant facile de passer de l'un à l'autre grâce à des mots-clés:
multi ensemble vers ensemble: distinct
ensemble vers multi ensemble: all

Les opérateurs ensemblistes (UNION, INTERSECT, MINUS) forcent par défaut la sémantique ensembliste. Nous verrons ces opérateurs plus tard. Pour forcer la sémantique multi ensemble, utiliser le mot clé 'ALL' après 'UNION', ... Il faut également être prudent sur les conversions, et se méfier du coût (opération de TRI) engendré par DISTINCT.

  1. mysql> select distinct chromosome from Gene;

Le renommage

Le renommage permet comme son nom l'indique de renommer un attribut afin de lui donner un nouveau nom dans le résultat de notre requête. Ce terme est surtout utilisé pour les requêtes d'agrégation que nous verrons plus tard.
Afin de renommer un attribut, il suffit de mettre le nom voulu derrière le nom de l'attribut sélectionné (on peut également utiliser le mot-clé as), tandis que pour séparer les attributs à sélectionner il faut une virgule.
Pour résoudre les soucis d'ambiguité on peut également préfixer l'attribut à afficher par le nom de sa relation (relation.nom)

Par exemple si l'on veut le nom des gènes du chromosome 1 que l'on renomme en num_acc:
  1. mysql> select nom as num_acc from Gene where chromosome=1;
  2. mysql> select nom num_acc from Gene where chromosome=1;
  3. mysql> select g.nom as num_acc from Gene as g where chromosome=1;
  4. mysql> select g.nom as num_acc from Gene g where chromosome=1;

Les conditions multiples

La spécificité de conditions est que c'est la seule partie des requêtes de sélection où on ne sépare pas les attributs par des virgules.
On utilise ici des mots-clés and et or.
Afin de mettre en place des priorités, on se base sur les maths. Donc and > or. Et on peut utiliser évidemment des paranthèses afin de prioriser des parties de requêtes.
  1. mysql> # nom et description des gènes du chromosome 1 ayant une position de départ > 1000000
  2. mysql> select nom, descr from Gene where chromosome=1 and debut>1000000;
  3. mysql> # nom et description des gènes du chromosome 1 ou du chromosome 2 ayant une position de départ > 1000000
  4. mysql> select nom, descr from Gene where chromosome=1 or (chromosome=2 and debut>1000000);

L'utilisation des caractères jokers

C'est une spécificité du SQL par rapport à l'agèbre relationnelle ou ce type de condition ne s'exprime pas.
dans la clause select: On peut lister tous les attributs avec le caractère *
dans la clause select: On peut utiliser les expressions arithmétiques sur les valeurs retournées
dans la clause where: On utilise le mot-clé like avec les caractères jokers %, _: % permet de dire "de 0 à n caractères" tandis que _ permet de dire de 0 à 1 caractère
dans la clause where: On utilise le mot-clé between pour encadrer une valeur numérique. Cela évite de mettre deux conditions (une avec < une avec >)
dans la clause where: On peut distinguer les valeurs nulles (donc les attributs pour lesquels on a une absence de valeur)en utilisant le mot-clé null. Attention, il ne faut confondre absence de valeur et valeur=''.
  1. mysql> # description des gènes dont le nom commence par T
  2. mysql> select descr from Gene where like 'T%';
  3. mysql> # toutes les infos sur les gènes
  4. mysql> select * from Gene;
  5. mysql> # position de début des amorces
  6. mysql> select nom, debut - 30 from Gene;
  7. mysql> # gènes dont la position de départ se situe entre 500000 et 1000000
  8. mysql> select * from Gene where debut between 500000 and 1000000;
  9. mysql> # gènes pour lesquels on n'a pas de description
  10. mysql> select * from Gene where description is null ;
  11. mysql> # gènes pour lesquels on a une description
  12. mysql> select * from Gene where description is not null ;

Avec ce qu'on a vu là, vous serez incollables sur les requêtes simples portant sur les attributs et la manière de filtrer les choses sur une seule table! Wow c'est un bon début. Maintenant regardons comment on fait pour relier les tables entre elles. Er partons pour le monde merveilleux des jointures #monPetitPoney

Trier les résultats

Par défaut, une requête SQL va renvoyer les résultats dans l'ordre dans lequel les données ont été inscrites dans la base. Il est possible de trier nos résultats en utilisant la clause order by
Voilà la syntaxe: selct a, b from ma_table order by a, b desc
On spécifie les attributs après order by dans l'odre dans lequel on veut trier, avec possibilité ascendante, ou descendante (on mettra desc après l'attribut).
Dans la syntaxe, on trie d'abord par l'attribut a de manière ascendante puis par b de manière descendante.

  1. mysql> # tri de la table personnes par nom puis prénom
  2. mysql> select * from personnes order by nom, prenom;
  3. mysql> # tri de la table gènes par chromosome, puis par nom dans l'ordre alpabétique inversé
  4. mysql> select * from genes order by chromosome, nom desc;

Limiter le nombre d'enregistrements en sortie

Une requête SQL peut renvoyer des dizaines, ou des centaines de résultats. Afin de limiter le nombre de lignes en sortie, on peut utiliser le mot-clé limit qui va donc limiter la sortie. Cette clause se met tout le temps à la toute fin de la requête, quoi qu'on fasse.
La syntaxe: select ... from ma_table limit x,y;
x: est le premier enregistrement que l'on va afficher (le xe dans la liste des résultats de la requête, y est le nombre de ligne qu'on affiche).

  1. mysql> # afficher les 10 premiers enregistrements de la table personnes
  2. mysql> select * from personnes limit 0,10;