Outdated version of the documentation. Find the latest one here.

16.4. Lesson: Requêtes

Lorsque vous écrivez une commande SELECT ..., cela est communément connu comme une requête - vous interrogez la base de données pour une information.

Objectif de cette leçon : Apprendre comment créer des requêtes qui retourneront des informations utiles.

Note

Si vous ne l’avez pas fait dans la leçon précédente, ajoutez les objets personnes suivants dans votre table people. Si vous recevez des erreurs liées à des contraintes de clé étrangère, vous devez d’abord ajouter l’objet ‘Main Road’ à votre table des rues.

insert into people (name,house_no, street_id, phone_no)
          values ('Joe Bloggs',3,2,'072 887 23 45');
insert into people (name,house_no, street_id, phone_no)
          values ('Jane Smith',55,3,'072 837 33 35');
insert into people (name,house_no, street_id, phone_no)
          values ('Roger Jones',33,1,'072 832 31 38');
insert into people (name,house_no, street_id, phone_no)
          values ('Sally Norman',83,1,'072 932 31 32');

16.4.1. Ordonner les résultats

Récupérons une liste de personnes triée par leur numéro de maison:

select name, house_no from people order by house_no;

Résultat:

     name     | house_no
--------------+----------
 Joe Bloggs   |        3
 Roger Jones  |       33
 Jane Smith   |       55
 Sally Norman |       83
(4 rows)

Vous pouvez trier les résultats par les valeurs de plus d’une colonne :

select name, house_no from people order by name, house_no;

Résultat:

     name     | house_no
--------------+----------
 Jane Smith   |       55
 Joe Bloggs   |        3
 Roger Jones  |       33
 Sally Norman |       83
(4 rows)

16.4.2. Filtrage

Souvent, vous ne voudrez pas voir chaque enregistrement individuel dans la base de données - en particulier s’il y a des milliers d’enregistrements et que vous êtes seulement intéressés à en voir un ou deux.

Voici un exemple d’un filtre numérique qui retourne seulement des objets pour lesquels house_no est inférieur à 50 :

select name, house_no from people where house_no < 50;

      name     | house_no
  -------------+----------
   Joe Bloggs  |        3
   Roger Jones |       33
  (2 rows)

Vous pouvez combiner les opérations de filtres (définies avec la clause WHERE ) avec les opérations de tri (définies en utilisant la clause ORDER BY):

select name, house_no from people where house_no < 50 order by house_no;

      name     | house_no
  -------------+----------
   Joe Bloggs  |        3
   Roger Jones |       33
  (2 rows)

Vous pouvez aussi filtrer sur les données du texte :

select name, house_no from people where name like '%s%';

      name     | house_no
  -------------+----------
   Joe Bloggs  |        3
   Roger Jones |       33
  (2 rows)

Ici nous utilisons la cause LIKE pour trouver tous les noms qui contiennent un s. Vous noterez que cette requête est sensible aux majuscules et minuscules, ainsi l’entrée Sally Norman ne sera pas retournée.

Si vous recherchez une chaîne de lettres indépendamment de la majuscule ou minuscule, vous pouvez faire une recherche insensible aux majuscules et minuscules en utilisant la clause ILIKE :

select name, house_no from people where name ilike '%r%';

       name     | house_no
  --------------+----------
   Roger Jones  |       33
   Sally Norman |       83
  (2 rows)

Cette requête retourne chaque personne avec un r ou R dans son nom.

16.4.3. Jointure

Et si vous voulez voir les détails de la personne et son nom de rue plutôt que l’ID ? Afin de faire cela, vous devez joindre le deux tables ensemble dans une seule requête. Regardons un exemple :

select people.name, house_no, streets.name
from people,streets
where people.street_id=streets.id;

Note

Avec les jointures, vous devez toujours définir les deux tables d’où proviennent les informations, dans notre cas personnes et rues. Vous devez également spécifier quelle clé sert à la correspondance (clé étrangère et clé primaire). Si vous ne spécifiez pas cela, vous allez obtenir une liste de toutes les combinaisons possibles de personnes et de rues, mais il ne sera pas possible de savoir qui habite dans quelle rue!

Voici à quoi la bonne sortie devra ressembler :

     name     | house_no |    name
--------------+----------+-------------
 Joe Bloggs   |        3 | Low Street
 Roger Jones  |       33 | High street
 Sally Norman |       83 | High street
 Jane Smith   |       55 | Main Road
(4 rows)

Nous reverrons des jointures plus tard lorsque nous créerons des requêtes plus complexes. Souvenez-vous juste qu’elles permettent de combiner d’une façon simple l’information de deux ou plusieurs tables.

16.4.4. Sous-sélection

Des sous-sélections vous permettent de sélectionner des objets d’une table sur la base des données d’une autre table qui est liée via une relation de clé étrangère. Dans notre cas, nous voulons trouver des personnes qui vivent dans une rue spécifique.

Faisons tout d’abord un petit ajustement de nos données :

insert into streets (name) values('QGIS Road');
insert into streets (name) values('OGR Corner');
insert into streets (name) values('Goodle Square');
update people set street_id = 2 where id=2;
update people set street_id = 3 where id=3;

Jetons rapidement un coup d’œil à nos données après ces changements; nous pouvons réutiliser notre requête de la section précédente :

select people.name, house_no, streets.name
from people,streets
where people.street_id=streets.id;

Résultat:

     name     | house_no |    name
--------------+----------+-------------
 Roger Jones  |       33 | High street
 Sally Norman |       83 | High street
 Jane Smith   |       55 | Main Road
 Joe Bloggs   |        3 | Low Street
(4 rows)

Nous allons maintenant vous montrer une sous-sélection de ces données. Nous voulons afficher seulement les personnes qui vivent dans la street_id numéro 1 :

select people.name
from people, (
    select *
    from streets
    where id=1
  ) as streets_subset
where people.street_id = streets_subset.id;

Résultat:

     name
--------------
 Roger Jones
 Sally Norman
(2 rows)

Bien que ce soit un exemple très simple et inutile avec nos petits jeux de données, il illustre à quel point les sous-sélections peuvent être utiles et importantes lors de requêtes sur des jeux de données grands et complexes.

16.4.5. Requêtes agrégées

Une des fonctionnalités puissantes d’une base de données est sa capacité à résumer les données dans ses tables. Ces résumés sont appelés requêtes agrégées. Voici un exemple typique qui nous dit comment plusieurs objets “personne” sont dans notre table personne :

select count(*) from people;

Résultat:

 count
-------
     4
(1 row)

Si nous voulons les totaux agrégés par nom de rue nous pouvons procéder ainsi:

select count(name), street_id
from people
group by street_id;

Résultat:

 count | street_id
-------+-----------
     2 |         1
     1 |         3
     1 |         2
(3 rows)

Note

Comment nous n’avons pas utilisé la clause ORDER BY, l’ordre de vos résultats peut ne pas correspondre avec ce qui est montré ici.

16.4.5.1. Try Yourself moderate

Résumez les personnes par nom de rue et montrez les noms de rue actuel à la place de street_ids.

Vérifiez vos résultats

16.4.6. In Conclusion

Vous avez vu comment utiliser des requêtes pour retourner les données dans votre base de données d’une façon qui vous permet d’y extraire de l’information utile.

16.4.7. What’s Next?

Ensuite vous verrez comment créer des vues depuis les requêtes que vous avez écrites.