Notes et transcription du cours Requêtez une base de données avec SQL disponible sur la plateforme Openclassrooms.
Voilà, vous connaissez maintenant les opérations les plus utilisées en SQL (tout au moins pour les requêtes de type SELECT).
Vous verrez, c'est très puissant. Mais… comme dit l'adage, “À grand pouvoir, grandes responsabilités”. En effet, il ne faut pas faire n'importe quoi quand vous écrivez une requête !
Connaître au moins une clé candidate par table (potentielle clé primaire), c'est très important.
Pourquoi ? Parce qu'elles déterminent la nature des objets que vous représentez dans une table.
On voit cela tout de suite en pratique !
On nous fournit un tableau extrait de la base “Panama Papers”. On ouvre le fichier avec un tableur. A première vue on a un tableau qui contient une liste de sociétés. Pour chacune on peut voir l'intermédiaire qui à participé à sa création.
Avant de commencer l'analyse on détermine le nombre de sociétés présentes dans le fichiers en comptant le nombre de lignes du document. Ce nombre d'enregistrements sert de base pour les analyses futures et pour établir les statistiques.
Mais en explorant plus en détail le tableau, on s’aperçoit que certaines sociétés sont présentent sur plusieurs lignes, car elles sont associées à plusieurs intermédiaires.
On s’aperçoit alors que le nombre de sociétés utilisé dans tous les calculs est faux car certaines sociétés étaient présentes en double voir en triple.
Ici notre erreur était qu'en parcourant le fichier, nous n'avions pas pensé qu'une société pouvait être associée à plusieurs intermédiaires. On a pensé à priori : une ligne = une société.
Cela revient à se dire que cette table pourrait avoir comme clé primaire la colonne id_entity
. Si cette colonne est clé primaire, il n' y a pas deux lignes qui ont la même valeur pour id_entity
, et donc une ligne = une société.
Cependant on constate bien que deux lignes peuvent avoir la même valeur id_entity
:
En fin de compte, une clé primaire pour cette table pourrait être id_entity
+ id_intermediary
.
Cette table est en fait le résultat d'une jointure entre la table entity
et la table intermediary
avec une table d'association entre les deux (association many-to-many) :
Comme cette table est le résultat d'une jointure avec une table d'association, alors une ligne ne représente pas une entité, ni même un intermédiaire mais plutôt une association entre entité et intermédiaire.
Si on compte le nombre de lignes, on ne compte donc pas des entités, mais plutôt des associations entre entité et intermédiaire. Et comme c'est une association plusieurs-a-plusieurs, on va compter des entités en double.
La conclusion, c'est que quand on a à faire à une table, il faut toujours vérifier que ce que l'on pense être une potentielle clé primaire, l'est vraiment.
Voilà, maintenant que vous savez qu'il est important de connaître ses clés primaires potentielles, voyons comment les déterminer.
Quand on interroge une BDD avec des requêtes qui commencent par SELECT, une seule requête ne suffit pas. En effet, on est souvent amené à effectuer plusieurs opérations à la suite, comme par exemple des jointures ou des filtrages. C'est ce que vous faites quand vous imbriquez des requêtes les unes dans les autres (souvenez-vous, nous avons déjà vu cela !)
Eh bien, à chaque résultat intermédiaire que vous obtiendrez, il faudra vous poser la question de la clé primaire.
Heureusement, vous ne devez pas spécifier au SGBDR la clé primaire de chaque résultat intermédiaire, mais posez-vous cette question à chaque fois : « Quelle serait la potentielle clé primaire que je donnerais à cette table si je devais l'enregistrer dans la BDD ?».
Mais alors, pour déterminer la potentielle clé primaire d'une table intermédiaire, comment fait-on ?
Vous pouvez tout à fait utiliser la méthode que l'on a vue précédemment dans le chapitre sur les clés primaires, en trouvant un groupe de colonnes unique et minimal.
Mais il y a quelques règles qui permettent d'aller plus vite :
Commençons par le cas du SELECT : quand vous sélectionnez quelques colonnes avec un SELECT, si parmi les colonnes que vous sélectionnez, il y a une potentielle clé primaire, alors cette clé peut être la clé primaire de votre résultat, c'est facile !
Mais si parmi les colonnes que vous sélectionnez, il n'y a pas de potentielle clé primaire, alors votre résultat… n'aura pas de clé primaire possible ! Vous aurez donc potentiellement des doublons dans la table. En général, les doublons, c’est problématique.
En effet, prenez cette requête, qui vous renverra environ 200 000 lignes :
SELECT STATUS FROM entity;
Ici, vous n’avez sélectionné que status
, qui ne peut pas être une clé primaire. Vous aurez donc des doublons, car sur les quelques 200 000 lignes que contient la table entity
, la colonne status
ne contient que 18 valeurs différentes. Si votre but est de connaître tous les statuts différents, alors supprimez les doublons en écrivant SELECT DISTINCT status FROM entity;
. Si par contre, vous voulez connaître les statuts de toutes les sociétés, alors sélectionnez quand même une clé primaire, afin de savoir quel statut correspond à quelle société : SELECT id, status FROM entity;
. Avec cette requête, plus de doublons !
Passons maintenant au WHERE, quand vous filtrez des lignes selon une condition.
Dans la plupart des cas, le WHERE ne modifie pas la clé primaire, sauf dans certains cas particuliers, où, une fois le filtrage appliqué, la clé primaire sera simplifiable.
Simplifiable, c'est-à-dire ?
Simplifiable ça veut dire que, si vous avez, avant le filtrage, une clé composée de 2 colonnes, par exemple, eh bien après le filtrage, vous pouvez ne garder qu'une colonne sur les 2 dans votre nouvelle clé primaire.
Alors, pour différencier si vous êtes dans le cas où la clé ne change pas, ou bien dans le cas où la clé est simplifiable après un WHERE, il n'y a pas vraiment de règle ; il faudra utiliser la bonne vieille méthode à laquelle vous êtes habitué : trouver un groupe unique et minimal.
Quand vous faites un produit cartésien entre 2 tables, (donc avec un FROM), alors la table résultante peut avoir comme clé primaire le regroupement des clés primaires des 2 tables. La jointure
Pour la jointure, ça va dépendre.
Rappelez-vous qu'une jointure entre A
et B
, c'est un produit cartésien puis un filtrage avec un WHERE.
A
et B
.Vous allez voir, suivez mon raisonnement !
Quand on fait une jointure, c'est très très souvent d'une clé étrangère d'une table A
vers une potentielle clé primaire d'une table B
.
A
, et c'est tout ! Ici, c'est le cas où le WHERE a simplifié la clé primaire.A
vers un groupe de colonnes de B
qui n'est pas unique (donc qui ne peut pas être clé primaire de B
). Dans ce cas, le résultat de votre jointure a comme clé primaire le regroupement des 2 clés primaires des 2 tables. En fait, c'est ce que nous avait donné le produit cartésien initial ; le WHERE n'a rien simplifié du tout. Si vous êtes dans ce cas plus rare, c'est possible, mais vérifiez bien que vous n'avez pas fait d'erreur de raisonnement, par exemple en comptant le nombre de lignes, comme on va le voir juste après.
Bien connaître ses clés, c'est également très important lors des jointures.
En général, on effectue une jointure :
A
…B
.Dans ce cas, le nombre de lignes de la table que vous obtiendrez aura :
A
si vous faites une jointure interne ;A
si vous faites une jointure externe à gauche (avec A
à gauche).À la fin de votre jointure, pensez bien à compter le nombre de lignes.
B
n'en est pas une ! Vous risquez de propager cette erreur tout au long de la chaîne de traitement de données !
J'ai déjà fait cette erreur. Il m'a fallu 1 jour entier pour remonter la chaîne et trouver la source d'un résultat incohérent en bout de chaîne.
En règle générale, dans votre condition de jointure de ce type :
A.cle_étrangere = B.cle_primaire
… assurez-vous qu'au moins l'un des 2 termes de part et d'autre du = soit une potentielle clé primaire.
Si ce n'est pas le cas, ce n'est pas interdit, mais vérifiez bien que vous ne faites pas une erreur de raisonnement. Soyez sûr que c'est ce dont vous avez vraiment besoin. Surtout, vérifiez bien la table finale en termes de cohérence, et surtout en termes de nombre de lignes.
Voilà ! Vous savez maintenant manier à merveille les requêtes SELECT. Mais pour notre enquête, cela ne suffit pas encore. Nous aurons besoin d'apprendre de nouvelles fonctionnalités pour nos requêtes.