Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zér0 > Les tutoriels > Non-Officiels > Site Web > PHP > Base de données > Voir tout le tutoriel

Pour aller plus loin...

Auteur : Shepard
Créé : le 12/04/2006 00:35:08
Modifié : le 29/05/2007 14:05:31
Avancement : 0%
Imprimer tout le tutoriel
C'est quoi tous ces trucs que je vois sur les forums et auxquels je ne comprends rien à rien ?? J'en ai marre de passer pour un idiot, que quelqu'un m'expliiiique !!


Tiens ben ça tombe bien : c'est justement pour ça que ce tutorial est conçu :p .
Comme pour tous les cours de ce site, on part de Zér0, ici je considérerai que Zér0, c'est le cours à M@teo... Donc avant de vous lancer, allez au moins relire ceci si votre cerveau vous paraît embrouillé sur certains points ;) .

Je vous conseille également fortement de lire les chapitres dans l'ordre, la plupart s'appuient sur des concepts vus précédemment. Mais si vous êtes attentif et que vous vous appliquez, vous vous demanderez bientôt pourquoi tous les Zér0s n'utilisent pas les techniques citées ici :D .

Ce cours est composé des parties suivantes :

Partie 1 : SELECT: Une puissance négligée

A la fin du cours de M@teo, vous croyiez peut-être tout savoir ?
Je vais vous démontrer le contraire rien que sur les requêtes SELECT !

Avant de commencer : utilisation de la console MySQL

Dans ce chapitre, vous allez apprendre à vous servir du client en ligne de commande de MySQL, c'est pour moi le moyen le plus simple et le plus rapide d'effectuer des tests avec MySQL.

Lancer le client

Sous Windows - WampServer



Lancer le client sous Windows avec WampServer, il n'y a rien de plus simple : dans la dernière version, soit WAMP5 1.6.0, il suffit de cliquer sur l'icône du systray (en supposant bien sur que WAMP5 est lancé), puis de cliquer sur MySQL console du menu MySQL. Entrez ensuite votre mot de passe (par défaut, appuyez simplement sur ENTRÉE). Voici ce que vous devriez obtenir (sous WAMP5 1.6.0) :

Image utilisateur

Image utilisateur



Sous Windows - Autres



Si vous n'utilisez pas Wamp, ou que vous n'aimez pas son menu ( :p ), il y a une autre solution : lancer le client avec la ligne de commande de Windows.

Pour commencer, il faut repérer le fichier mysql du dossier d'installation de mysql. Ca pourrait être : "C:\Program Files\EsayPHP1-8\mysql\bin\mysql.exe".

Appuyez simultanément sur la touche "Windows" du clavier (entre "ctrl" et "alt" en bas à gauche) et sur R pour lancer l'exécuteur Windows. Tapez ensuite "cmd" puis ENTER.

Ensuite, il faut commencer par aller dans le répertoire où se trouve mysql.exe grâce à la commande "cd". Enfin, pour lancer le client, il faut faire "mysql.exe --user=root --password=mot_de_passe. Ce qui donne :

Code : Console
cd "C:\Program Files\EasyPHP1-8\mysql\bin"

mysql.exe --user=root


Généralement, vous pouvez remplacer utilisateur par root et omettre la clause --password.

En images : (remarquez que j'exécute directement la commande dans l'exécuteur de Windows, si vous n'y arrivez pas de cette façon, reprenez la méthode du dessus).

<lien url="uploads/fr/files/10001_11000/10220.png"></lien><lien url="uploads/fr/files/10001_11000/10220.png"/>
<lien url="uploads/fr/files/10001_11000/10222.png"/>



Sous Unix ( Linux, BSD,...)



Sous Unix, lancez une console et tapez mysql -u root ( Et ça fait une belle claque pour tous ceux qui disent que Windows est plus simple que Linux ^^ ).

Image utilisateur

Tests : est-ce que ça marche ?

On va maintenant voir si tout marche bien sur notre installation de MySQL.

Test 1 : test des fonctionnalités



Lancez cette commande :

Code : SQL
1
SELECT 'essai' AS test;


Vous devriez voir ceci (ou quelque chose qui y ressemble en tout cas, dans le cas contraire, bah postez un message sur le forum :p ) :

Image utilisateur

Test 2 : test des droits



Normalement, vous devriez être logué en tant que root : sous Windows, c'est fait automatiquement la plupart du temps, et je vous ai expliqué sous linux comment vous loguer en tant que tel.

Nous allons, histoire d'être sûrs, tester que nous avons bien les droits create et drop, logiquement, si vous avez ces deux là, vous devriez tous les avoir.

Lancez donc ces deux commandes l'une après l'autre et regardez si vous obtenez à peu près le même résultat que moi :

Code : SQL
1
2
3
4
5
SHOW DATABASES;
CREATE DATABASE abcxtest;
SHOW DATABASES;
DROP DATABASE abcxtest;
SHOW DATABASES;


Image utilisateur

Si vous avez le même que moi, c'est bon ! Sinon vous n'êtes probablement pas connecté en tant que root, auquel cas je vous conseille, sous linux, de relire la sous-partie précédente, et sous Windows, de vérifier vos paramètres de connection, et, pourquoi pas, d'ajouter -u root à votre ligne de commande (-u root -p si vous avez configuré un mot de passe pour root).

Quelques explications...

Bon, c'est bien beau tout ça : ça fonctionne, ça va vite, ça fait pro, c'est beau,...

Oui mais pourquoi quand je fais ça : SELECT 'bonjour', ça m'affiche deux fois "bonjour" dans un tableau ?

En fait, la première ligne du tableau comporte les noms des différentes colonnes, tandis que les lignes suivantes comportent les données. Reprenons l'exemple précédent :

Image utilisateur

On voit bien, dans le résultat de la dernière requête par exemple, que "Database" est le nom de la colonne, et que "information_schema", "mysql" et "test" sont les données contenues dans cette colonne (en l'occurence les noms des différentes bases de données présentes sur le serveur).

Comme vous avez pu le constater, la console MySQL est très pratique pour effectuer quelques tests avant de mettre la requête dans PHP. De plus elle répond trés rapidement par rapport au chargement d'une page PHP.

Sélectionner une valeur... ne provenant pas d'une table !

Un premier chapitre peut-être pas des plus attractifs mais nécessaire pour la suite.

Vous vous demandez plus que certainement à quoi peut bien servir une requête appelant des données ne provenant pas d'une table. Je vous le dis tout de suite, pas à énormément de choses, mais dans certains cas, ça peut être très pratique.

Nous verrons plusieurs cas : simplement sélectionner une valeur, sélectionner une valeur ayant subi des "transformations", les variables utilisateur et enfin les fonctions utilisateur (qui n'existent qu'à partir de MySQL 5).

Allez, c'est parti !

Quelques bases...

Sélectionner une valeur



Essayez donc d'exécuter la requête suivante :

Code : SQL
1
SELECT 'bonjour';

Image utilisateur

Vous vous demandez peut-être pourquoi je vous montre ça, et bien juste parce que beaucoup d'entre vous ne savez pas que la clause FROM n'est pas obligatoire dans une requête SELECT ! Vous vous en doutez certainement vu le titre de ce chapitre : la plupart des requêtes qui suivent seront basées sur le même modèle... :p

Utilisation des apostrophes



A propos, faisons une petite mise au point à propos de l'utilisation des apostrophes autour des valeurs ...



Il est fortement conseillé d'utiliser les apostrophes et non pas les guillemets car la norme SQL prévoit l'utilisation des apostrophes et non des guillemets. Respecter la norme vous permettra d'éviter bien des déboires si vous décidez un jour de changer de moteur de gestion de base de données (PostGreSQL, SQLite,... )


Pour écrire une apostrophe, il suffit de la doubler :
Code : SQL
1
SELECT 'On m''appelle Shepard';

Image utilisateur


Il est fortement recommandé de toujours terminer ses requêtes par un point-virgule. Pourquoi ? Parce que quand on en arrivera au chapitre sur les transactions, si vous n'avez pas encore pris cette habitude, vous risquez d'être confrontés à quelques ennuis. Retenez simplement ceci : toute requête SQL doit se terminer par un point-virgule.

Le renommage de colonnes avec AS



Bien sûr, on peut sélectionner plusieurs valeurs en les séparant par des virgules :
Code : SQL
1
SELECT 'bonjour', 1, '01:25:18';


Qui renvoie :
Image utilisateur


Vous remarquez que les noms de colonnes ne sont pas vraiment... pratiques. C'est pour ça qu'existe le renommage de colonnes. Exemple :
Code : SQL
1
SELECT 'bonjour' AS exemple_texte, 1 AS exemple_nombre, '01:25:18' AS exemple_heure;


Résultat :
Image utilisateur


On peut aussi mettre des noms plus exotiques grâce aux accents :
Code : SQL
1
SELECT 'bonjour' AS `Du texte`, 1 AS `Un chiffre`, '01:25:18' AS `De l'horodatage`;


Image utilisateur


Remarquez les espaces et l'apostrophe dans le nom. Il est toutefois vivement contre-indiqué d'utiliser des noms pareils car le traitement PHP s'en trouvera fortement pénalisé.

Les opérateurs mathématiques



Il existe 7 opérateurs principaux sous MySQL:



La division entière retourne toujours un nombre arrondi à l'unité inférieure ! Ne vous étonnez pas si vos calculs sont incorrects si vous utilisez à un moment ou à un autre des nombres décimaux et que vous utilisez DIV plutôt que /.

Toutefois, il est préférable, pour des raisons d'optimisation, d'utiliser 5 DIV 4 que ROUND( 5 / 4 ). (Vous apprendrez l'utilisation de ROUND dans quelques minutes).

Exemple



Code : SQL
1
SELECT ( 1.0 + 5.0 * 6.0 MOD ( 4.0 % 3.0 ) ) / ( 2.0 / 0.25 ), 0.12 DIV 1;

Image utilisateur


Notez que tout ce que j'ai dit dans cette sous-partie ne concerne pas uniquement MySQL. Tous les SGBDR (Système de Gestion de Base de Données Relationnelle) utilisent le doublage de l'apostrophe, le point-virgule final,... ou du moins tous les SGBDR respectant la norme.

Les fonctions MySQL

C'est peut-être assez con à dire, mais M@teo ne dit à aucun moment qu'il existe des fonctions aussi dans MySQL. Le seul soupçon que vous pourriez avoir par rapport à leur existence était le moment où vous avez appris à compter le nombre de lignes avec COUNT(col).

Il existe une floppée de fonctions MySQL telles que COUNT, certaines agissant sur des chaînes de caractères, d'autres sur des nombres, d'autres sur des dates, certaines sur les colonnes d'une table,...

Comme nous ne travaillons pas sur des tables, nous nous passerons pour le moment de la dernière catégorie, je vous apprendrai dans cette sous-partie les fonctions principales ainsi que leur utilité. Bonne lecture !

UPPER / LOWER



Exemple



Code : SQL
1
SELECT UPPER('C''est un assassinat !!') AS majs, LOWER('NON ?') AS mins;

Image utilisateur


Effets



UPPER met une chaîne en majuscules et LOWER met une chaîne en minuscules. Seuls les caractères alphabétiques sont pris en compte.

Utilisation



Plusieurs utilisations, dont certaines sont contre-indiquées :


CHAR_LENGTH



Exemple



Code : SQL
1
2
SELECT CHAR_LENGTH('Bonjour tout le monde !!');
SELECT CHAR_LENGTH('Il l''a');

Image utilisateur


Effets



CHAR_LENGTH renvoie le nombre de caractères contenus dans une chaîne.
La fonction LENGTH sert à la même chose mais tient compte des caractères codés sur 2 octets ! Attention donc aux surprises avec LENGTH que je vous déconseille d'utiliser !


Utilisation



CHAR_LENGTH peut être utilisé comme une vérification (vérifier qu'un pseudo ne contient pas plus de n caractères, etc). Vous allez me dire qu'on peut faire ça du côté PHP, mais moi je trouve ça plus facile du côté SQL, on va dire : "Chacun ses goûts" ;) .

CONCAT et CONCAT_WS



Exemple



Code : SQL
1
SELECT CONCAT('Bon', 'jour'), CONCAT_WS(', ', 1, 2, 3, 4, 5);

Image utilisateur


Effets



Joindre deux chaînes :p .

La norme SQL prévoit deux moyens pour concaténer : CONCATENATE et l'opérateur || (l'opérateur étant plus largement utilisé). Par exemple, sous PostGreSQL :
Image utilisateur

MySQL ne suit pas la norme et crée une autre fonction : CONCAT.

L'opérateur || n'existe tout simplement pas en MySQL, enfin si il existe, mais il ne sert pas du tout à concaténer :p .

Utilisation



Imaginez que vous avez créé un forum où on peut entrer son nom et son prénom. Vous avez stocké ces données dans deux champs distincts. Dans un tableau HTML, vous n'allez tout de même pas écrire le nom et le prénom dans deux colonnes différentes :p . Donc vous utilisez CONCAT.

CONCAT_WS est moins connu mais parfois très utile ! Il permet de concaténer des chaînes mais d'insérer entre chaque chaîne des caractères. On en reparlera dans le chapitre sur les variables utilisateur :) .

LEFT / RIGHT / SUBSTRING



Exemple



Code : SQL
1
SELECT LEFT('bonjour', 3) AS gauche3, RIGHT('bonjour', 1) AS droite1, SUBSTRING('Bonjour' FROM 2 FOR 3) AS souschaine23;

Image utilisateur


Effets



LEFT('chaine', n) prend n caractères de 'chaine' en partant de la gauche.
RIGHT('chaine', n) prend n caractères de 'chaine' en partant de la droite.
SUBSTRING('chaine' FROM m FOR n) prend n caractères de 'chaine' en partant du caractère m.

Utilisations



Vous vous souvenez de ce qu'on a dit avec UPPER et LOWER à propos du formatage de nom / prénom ? Eh bien maintenant vous savez le faire :p :) .

Essayez de trouver la requête vous-même, puis regardez la solution ;) .
Note : les données sont dans deux champs différents, rassemblez-les en un seul histoire d'augmenter un (tout petit) peu la difficulté :diable: . Résultat à obtenir : NOM Prénom à partir de Nom prenoM :) .

Secret (cliquez pour afficher)
Code : SQL
1
SELECT CONCAT(UPPER('nom'), ' ', UPPER(LEFT('prenoM', 1)), LOWER(SUBSTRING('prenoM' FROM 2)));

Image utilisateur


Quelques fonctions mathématiques...



Les fonctions mathématiques s'utilisent pour faire des mathématiques, qui sont des outils universels et utilisables presque partout. Inutile de vous faire une liste de toutes les possibilités qu'elles offrent. Voici un tableau assez éloquent selon moi :

FonctionDescriptionRésultat
CEIL(2.318) Arrondit à l'entier supérieur 3
FLOOR(1.942) Arrondit à l'entier inférieur 1
ROUND(1.452, 2) Arrondit 1.452 à 2 décimales. On peut arrondir à un nombre négatif. 1.45
SIN(0), COS(0), TAN(0), COT(0) Donne les sinus, cosinus, tangente et cotangente de 0 (angle exprimé en radians). 0, 1, 0, NULL
ASIN(0), ACOS(0), ATAN(0) Donne les arcsinus,... de 0 (l'intervalle ca de -1 à 1 pour ASIN et ACOS). 0, 1.5707963267949, 0
PI() Donne la valeur de Pi. 3.141593
DEGREES(1) Convertit 1 radian en degrés 57.295779513082
RADIANS(60) Convertit 60 degrés en radians 1.0471975511966
RAND() Renvoie un nombre aléatoire entre 0 et 1 0.54017342584224
SQRT(4) Renvoie la racine carrée de 4 2


NOW() / CURRENT_TIME() / CURRENT DATE()



Exemple



Code : SQL
1
SELECT NOW(), CURRENT_DATE(), CURRENT_TIME();

Image utilisateur


Effets



NOW() renvoie le timestamp (pas le timestamp UNIX) actuel, CURRENT_TIME() renvoie l'heure et CURRENT_DATE() la date.

Utilisations



Ces valeurs sont très utiles dans les valeurs par défaut de certains champs dans certaines tables. Par exemple, si vous faites un script de news et que vous stockez la date à laquelle a été postée la news, mettre NOW() comme valeur par défaut du champ concerné est une technique fortement conseillée :) .

FROM_UNIXTIME() / UNIX_TIMESTAMP()



Exemple



Code : SQL
1
SELECT FROM_UNIXTIME(1144835054), UNIX_TIMESTAMP(NOW()), UNIX_TIMESTAMP();

Image utilisateur


Effets



FROM_UNIXTIME() vous permet de passer d'un timestamp UNIX (par exemple obtenu par PHP) à un timestamp SQL (mieux adapté aux bases de données). Il est déconseillé de stocker des timestamps UNIX dans une BDD, c'est pourquoi ces fonctions existent pour permettre une conversion simple et efficace.

UNIX_TIMESTAMP() vous permet de revenir à un format UNIX ou d'obtenir le timestamp UNIX actuel si aucune date n'est spécifiée en argument. Normalement, cette fonction ne devrait jamais être utilisée : PHP ne devrait plus avoir à traiter des variables de type DATETIME après une requête SQL ; il vaut mieux traiter les dates dans la requête SQL via DATE_FORMAT(), GET_FORMAT() et EXTRACT() (voir juste en dessous).

Utilisation



Ces fonctions servent à stocker une date provenant de PHP dans une BDD au format date SQL. Elles permettent également de revenir à un timestamp UNIX, mais comme ça a déjà été dit, il vaut mieux ne plus traiter de dates du côté de PHP.

DATE_FORMAT() / GET_FORMAT() / EXTRACT()



Exemple



Code : SQL
1
2
3
SELECT DATE_FORMAT(CURRENT_DATE(), GET_FORMAT(DATE, 'EUR')) AS today,
DATE_FORMAT(NOW(), '%d.%m.%Y') AS today2,
CONCAT_WS('.', EXTRACT(DAY FROM NOW()), EXTRACT(MONTH FROM NOW()), EXTRACT(YEAR FROM NOW())) AS today3;

Image utilisateur


Effets



DATE_FORMAT() permet de formater une date selon divers formats fournis soit par vous-même (le truc bizarre avec les signes %), soit par GET_FORMAT(). Toutes les options disponibles pour ces deux options peuvent être trouvées sur cette page (je vais pas copier la doc non plus ^^ :p ) :


Utilisation



Ces fonctions sont utilisées pour rendre des dates au format français, c'est très pratique et ça permet de ne pas devoir intervenir du côté PHP. A préférer aux fonctions UNIX (et donc au traitement du côté PHP).

Et voilà, bien sûr, il existe beaucoup plus de fonctions dans MySQL, mais je crois vous avoir donné les principales, et en tout cas les plus utiles ;) :) .

Les fonctions utilisateur

Saviez-vous que, en plus des fonctions préexistantes fournies par MySQL, vous pouviez créer vos propres fonctions à partir de MySQL 5 ?

Dans cette partie, je ne vais pas vous expliquer comment créer vos propres fonctions, on n'a pas encore le niveau, mais je voulais juste vous dire que ça existait, et vous donner un petit exemple :p :) .

Les fonctions utilisateur ont des utilités multiples, de plus, elles peuvent retourner des valeurs qui pourraient être utilisées directement dans une requête. Une seule contrainte : l'appel de la fonction, admettons que vous ayez créé une fonction nommée 'f_format_nom_prenom' qui prend deux arguments (nom et prenom), vous ne pourriez lancer une requête de ce style (ça ne marcherait pas) :

Code : SQL
1
f_format_nom_prenom('pijcke', 'fabiaN');


Le SELECT est obligatoire ! Voici ce qu'il aurait fallu faire :

Code : SQL
1
SELECT f_format_nom_prenom('pijcke', 'fabiaN');


Encore une fois, la clause FROM est absente, pourtant dans la fonction, il peut très bien y avoir des SELECT sur des tables, mais on n'en a pas besoin dans la requête qui appelle la fonction :) .

Juste pour vous montrer à quoi ça ressemble, voici comment on aurait pu coder la fonction f_format_nom_prenom :

Code : SQL
1
2
3
4
CREATE FUNCTION
        f_format_nom_prenom ( nom VARCHAR(25), prenom VARCHAR(25) )
        RETURNS VARCHAR(50) LANGUAGE SQL READS SQL DATA
RETURN CONCAT(UPPER(nom), ' ', UPPER(LEFT(prenom, 1)), LOWER(SUBSTRING(prenom FROM 2)));


Bien sûr, une fonction peut contenir beaucoup plus de lignes, on ajoute alors les mots-clefs BEGIN et END, mais on verra tout ça plus tard...

Voici comment on utilise cette fonction :

Code : SQL
1
SELECT f_format_nom_prenom('pijcke', 'fabian') AS shepard;

Image utilisateur


Pas si mal pour 4 petites lignes de code ^^ :p .

C'était pas trop dur ? :p

Bon comme je vous l'avais dit, ce chapitre est doté d'un pouvoir assez... soporifique, j'espère au moins que vous avez eu 20 / 20 au Q.C.M. ! :ange:

Les variables utilisateur

Voici un chapitre qui devrait en intéresser plus d'un !

Ce chapitre vous permettra de faire plein de trucs géniaux, de plus, très peu savent ce que sont les variables utilisateur, donc profitez en : même M@teo ne savait pas ce que c'était avant de lire ce tuto :D :p (pour ceux qui voudraient savoir comment moi je l'ai appris, dites-vous simplement que je me suis farci toute la doc ^^ ).

Bon amusement !

Variables utilisateur ?

Vous vous demandez sans doute ce que c'est :p .

En fait il s'agit simplement de variables, exactement comme dans PHP, à quelques différences près :


Déclarer et utiliser une variable

Il y a plusieurs façons de définir une variable, il n'y en a pas une "meilleure" que l'autre, on utilise l'une dans certains cas, et l'autre dans d'autres.

Déclarer une variable avec SET



SET permet de déclarer une variable. Par exemple :

Code : SQL
1
SET @une_variable = 1;


On peut également utiliser une requête comme valeur de cette variable (en fait ce qu'on va faire s'appelle une sous-requête, mais on apprendra ça un peu plus tard :) ).

Ne vous préoccupez pas trop de ce code, essayez juste de le comprendre, nous apprendrons plus tard la signification de chacunes de ces lignes.

Code : SQL
1
2
3
4
5
6
CREATE DATABASE tests;
USE tests;
CREATE TABLE test ( a int );
INSERT INTO test VALUES (1), (2), (3), (4), (6), (9), (19), (34), (72);

SET @a := ( SELECT COUNT(*) FROM test ); -- Définition d'une variable grâce à une sous-requête

Image utilisateur


Sélectionner une variable avec SELECT



Pour sélectionner une variable, rien de plus simple, il suffit de faire :
Code : SQL
1
SELECT @mavariable;


Nous venons de définir deux variables : @une_variable et @a, regardons maintenant ce qu'elles contiennent ...

Code : SQL
1
SELECT @une_variable, @a;

Image utilisateur


Mais que vaut une variable non définie, par exemple @aetuo (pour ceux qui se demandent d'où ça vient, c'est azertyuiop en tirant une lettre sur deux :D ) :

Code : SQL
1
SELECT @aetuo;

Image utilisateur


Comme vous le voyez, ça ne renvoie pas d'erreur, ça ne renvoie tout simplement... rien. o_O

En fait une valeur est bien renvoyée : la valeur NULL, cette valeur est l'objet du prochain chapitre, donc je ne détaillerai pas plus ce phénomène ici. ;)

(re)Définir une variable avec SELECT



On peut également donner une valeur à une variable grâce à SELECT (ou UPDATE ou INSERT ou DELETE mais nous ne parlerons que de SELECT, sachez juste que c'est possible).

On définit une variable grâce à l'opérateur := (comme en Delphi pour ceux qui connaissent). La plupart du temps, les variables sont définies la première fois avec SET puis manipulées avec SELECT, mais il n'est pas rare que des exceptions enfreignent cette règle.

Définissons @a à 4:
Code : SQL
1
SELECT @a := 4;

Image utilisateur


Comme vous le voyez, SELECT renvoie directement la valeur vu que @a := 4 est considéré comme une colonne. On aurait très bien pu rajouter un AS pour redéfinir le nom de cette colonne.

Tiens à votre avis, est-il possible de donner à une colonne un nom contenu dans une variable ? Faisons le test :
Code : SQL
1
2
SET @nom = "colonne";
SELECT 4 AS @nom;

Image utilisateur


Comme vous le voyez, ça ne fonctionne malheureusement pas. C'est dommage, car ça aurait ouvert des voies pour la linéarisation de données (lignes en colonnes ou colonnes en lignes). Si toutefois quelqu'un trouve une astuce pour contourner ce problème, je lui serais fortement reconnaissant de me dire comment faire.

Mini-TP : un classement

Le problème ...



Enormément de choses sont possibles grâce aux variables utilisateur ! Cependant la plupart des applications possibles demandent plus de connaissances que ce que vous êtes censé savoir. Il y a cependant une chose que vous devriez être capable de faire en cherchant un peu : un système de classement !

Le but ? Je vous donne une table avec des pseudos associés à des points, vous devez réussir à donner une place à chacun de ces pseudos en fonction de son nombre de points. Chaque pseudo a un nombre de points différents (pas d'égalité donc), en effet la gestion des ex-aequos rendrait l'exercice bien trop difficile pour votre niveau actuel. :p

Quelques indices supplémentaires :


Voici les requêtes pour la création de la table :
Code : SQL
1
2
CREATE TABLE joueurs ( pseudo VARCHAR(30), points INT );
INSERT INTO joueurs ( pseudo, points ) VALUES ( 'Shepard', 13854 ), ( 'Alexi', 4251 ), ( 'Janne', 11245 ), ( 'Shagrath', 1248 ), ( 'Fred', 42857 );


Vous devez obtenir ce tableau :
Image utilisateur


Il ne me reste plus qu'à vous souhaiter bonne chance !

Une solution



En SQL, il n'y a jamais qu'un seul moyen de faire, ce qu'il y a dans la case secrète représente donc une solution, peut-être que la vôtre est radicalement différente (ça m'étonnerait un peu quand même mais bon :p ), mais ce qui compte à ce niveau, c'est que ça fonctionne ! Le principal c'est d'avoir cherché et d'être tombé sur quelque chose de potable, si vous n'y êtes pas arrivé, ne vous inquiétez pas : c'était le premier et il y en aura sans doute d'autres. ;) :)

Bon, assez blablaté. ^^

Secret (cliquez pour afficher)

Code : SQL
1
2
SET @place = 0;
SELECT @place := @place + 1 AS place, pseudo, points FROM joueurs ORDER BY points DESC;

Image utilisateur


Comme vous le voyez, les requêtes ne sont pas longues du tout (ce n'est pas pour rien que je disais que c'était de votre niveau :-° ), néanmoins il fallait y penser ! Je félicite ceux qui ont trouvé, mine de rien ce n'était pas si facile !

Un autre exemple : sélection au hasard

J'ai hésité à ajouter cette sous-partie à ce chapitre. En effet, elle fait appel à des notions dont vous n'avez certainement jamais entendu parler, je l'ai ajoutée quand même, dites-vous qu'il ne s'agit que d'un exemple, si vous ne comprenez pas tout à fait, ne vous inquiétez pas, on reviendra plus tard dans le cours sur tout ce qui sera montré ici. ;)


Le problème



On a une table nommée livreor (id, auteur, message) qui contient des messages contenus dans un livre d'or, on aimerait sélectionner un message au hasard. Chaque message a un identifiant unique.

On peut distinguer deux cas à ce stade :



Cas 1 : les identifiants sont continus



Code : SQL
1
2
3
4
5
6
7
8
CREATE TABLE livreor ( id INT AUTO_INCREMENT, auteur VARCHAR(30), message TEXT, PRIMARY KEY(id) );
INSERT INTO livreor ( auteur, message )
VALUES 
        ( 'Shepard', 'Tres bon site :p' ),
        ( 'Alexi', 'Vive Children of Bodom !' ),
        ( 'Shepard', 'Entierement d''acord, Alexi :)' ),
        ( 'Janne', 'Vive le synthe :-°' ),
        ( 'Alexi','N''importe quoi ! C''est la guitare qui est mieux :D' );


Rien que dans ce cas-là, les variables MySQL sont déjà très utiles, je vous conseille de bien comprendre ce cas-ci car sinon vous risquez de vraiment avoir du mal pour le second... :p

En fait, il suffit de trouver un nombre au hasard pris entre 1 et n, n étant le nombre de messages.

On peut récupérer très facilement n grâce à la requête suivante :

Code : SQL
1
SELECT COUNT(*) FROM livreor;


Ensuite on va utiliser la fonction RAND() pour prendre un nombre au hasard entre 0 et n - 0.000(...)01 :

Code : SQL
1
SELECT RAND() * COUNT(*) FROM livreor;


Utilisons maintenant la fonction FLOOR pour arrondir à l'entier inférieur. On aura alors un nombre entre 0 et n - 1. Il faudra donc ajouter un au résultat pour avoir un nombre entre 1 et n :

Code : SQL
1
SELECT FLOOR( RAND() * COUNT(*) ) + 1 FROM livreor;


Il suffit maintenant de prendre le message ayant pour identifiant le résultat de cette requête :

Code : SQL
1
SELECT auteur, message FROM livreor WHERE id = FLOOR( RAND() * ( SELECT COUNT(*) FROM livreor ) ) + 1;


Oui mais non ! Il y a un petit problème... RAND() est réévalué à chaque ligne, ce qui fait qu'avec cette requête, on peut avoir des bizarreries de ce genre là :
Image utilisateur


Comme vous le voyez, ça ne marche pas toujours, des fois on a 3 lignes, et des fois on n'en a pas du tout !

Pour y remédier, il suffit de stocker RAND() quelque part... Où ça ? Dans une variable pardi ! Sauf qu'au lieu de juste stocker le RAND(), on va y mettre tout le FLOOR(...) + 1. Ainsi on aura un nombre entier (plus rapide à stocker) et la requête sera simplifiée :

Code : SQL
1
2
SET @id_hasard = FLOOR( RAND() * ( SELECT COUNT(*) FROM livreor ) ) + 1;
SELECT auteur, message FROM livreor WHERE id = @id_hasard;

Image utilisateur


Bien sûr, il faut réexécuter le SET avant chaque SELECT, sinon @id_hasard garde la même valeur et on obtient toujours le même message.

Et le tour est joué ! (J'espère que jusque là vous avez suivi parce que les choses vont se compliquer à partir de maintenant :p ).


Cas 2 : les identifiants sont discontinus



Code : SQL
1
2
3
4
5
6
7
8
9
DROP TABLE livreor;
CREATE TABLE livreor ( id INT AUTO_INCREMENT, auteur VARCHAR(30), message TEXT, PRIMARY KEY(id) );
INSERT INTO livreor ( id, auteur, message )
VALUES 
        ( 2, 'Shepard', 'Tres bon site :p' ),
        ( 3, 'Alexi', 'Vive Children of Bodom !' ),
        ( 6, 'Shepard', 'Entierement d''acord, Alexi :)' ),
        ( 9, 'Janne', 'Vive le synthe :-°' ),
        ( 12, 'Alexi','N''importe quoi ! C''est la guitare qui est mieux :D' );


Là ça se complique un peu : si on prend un nombre au hasard entre 1 et le nombre de lignes, toutes les dernières lignes ne seront pas prises en compte et les "trous" pourraient être sélectionnés, donc ça ne va vraiment pas.

Une autre solution serait de prendre un nombre au hasard entre 1 et le dernier id de la table, puis de prendre l'id en dessous de ce nombre qui se rapproche le plus de ce nombre, mais je n'aime pas cette technique, tout d'abord parce que s'il y a des "gros" trous (suppression de 2000 messages d'affilée par exemple), le message juste avant ce trou reviendra plus souvent que les autres, et ensuite parce que cette méthode est plus compliquée que celle que je vais vous montrer. :p

Il y a une astuce : créer une table temporaire (donc qui ne dure que le temps de la session) avec une colonne contenant des chiffres continus (donc on retombe dans le premier cas), plus une autre colonne contenant les "vrais" id.

Pour créer cette table, rien de plus simple : on se base sur le principe du classement, sauf qu'il n'est plus nécessaire de préciser le ORDER BY :

Code : SQL
1
2
SET @place = 0;
CREATE TEMPORARY TABLE temp_livreor AS SELECT @place := @place + 1 AS place, id FROM livreor;


Histoire de nous assurer que tout fonctionne bien ...
Code : SQL
1
SELECT * FROM temp_livreor;

Image utilisateur

Remarquez qu'en général, je n'utilise jamais l'étoile qui permet de sélectionner tous les champs d'un coup, si je le fait ici, c'est parce que je veux m'assurer qu'il n'y ait rien en trop. :)

A partir de maintenant c'est facile : il suffit d'utiliser la même technique que tout à l'heure pour choisir une entrée de la table temp_livreor, puis de prendre le "vrai" id qui lui correspond, et d'afficher les infos correspondant à cet id. :)

Par exemple :

Code : SQL
1
2
3
SET @place_hasard = ( SELECT FLOOR( RAND() * ( SELECT COUNT(*) FROM temp_livreor ) ) + 1 );
SET @id_hasard = ( SELECT id FROM temp_livreor WHERE place = @place_hasard );
SELECT auteur, message FROM livreor WHERE id = @id_hasard;


Ou encore :

Code : SQL
1
2
SET @place_hasard = ( SELECT FLOOR( RAND() * ( SELECT COUNT(*) FROM temp_livreor ) ) + 1 );
SELECT auteur, message FROM livreor WHERE id = ( SELECT id FROM temp_livreor WHERE place = @place_hasard );


Il est également possible de le faire avec une jointure :

Code : SQL
1
2
SET @place_hasard = ( SELECT FLOOR( RAND() * ( SELECT COUNT(*) FROM temp_livreor ) ) + 1 );
SELECT auteur, message FROM livreor NATURAL JOIN temp_livreor WHERE place = @place_hasard;


La meilleure solution est la dernière, mais les deux autres sont évidemment tout à fait valables :) (ne vous inquiétez pas si vous ne comprenez pas les deux dernières requêtes : c'est normal ^^ ).

Les trois techniques fonctionnent et renvoient le même message si on ne modifie pas @place_hasard (évidemment). Voici ce que ça donne dans la console :

Image utilisateur


Voilà, j'admet que cette sous-partie était ardue et impossible à comprendre en entier si vous n'aviez lu que le cours de M@teo. Je ne peux que vous conseiller de venir le relire une fois que vous saurez ce que sont les jointures, les sous-requêtes et les tables temporaires. ;) :)

Alors ? C'était sympa comme matière non ?

Bien qu'on n'ait vu que quelques utilisations de ces variables, il faut bien vous rendre compte que les possibilités sont énormes ! MySQL est l'un des seuls SGBDR à inclure ce type de fonctionnalité, donc faites attention si vous comptez changer de moteur par la suite : vos requêtes ne seront pas compatibles !

Pour moi, les variables utilisateur sont l'une des choses qu'il manque à la norme SQL, bien sûr il faudrait les améliorer un peu (pouvoir renommer une colonne selon la valeur d'une variable par exemple :p ), mais ce serait sans aucun doute une forte avancée pour le monde de SQL. Je trouve dommage qu'elles soient si peu utilisées, leur potentiel est sous-estimé, j'espère que bientôt, les développeurs se rendront compte des fonctionnalités qu'elles permettent !

Traitement des "NULL"s

Voici un autre chapitre intéressant : le traitement des valeurs nulles, autrement dit le traitement d'une absence de valeurs !

Encore une fois, peu de développeurs se servent de cette fonctionnalité ! Pourtant les valeurs nulles sont pratiquement indispensables dans une base de données. L'exemple le plus flagrant est un profil dans un espace membre : la plupart des codeurs mettent une chaîne vide ( '' ) pour indiquer qu'il n'y a pas de valeur, alors qu'il serait plus simple de mettre un simple NULL, qui peut être traité beaucoup plus facilement par la suite dans les requêtes SELECT grâce aux fonctions que nous verrons dans ce chapitre. :)

Je vous laisse lire tout ça, bonne lecture !

Spécificités des valeurs nulles

La valeur NULL n'est pas une valeur comme les autres. En général, on la considère comme une valeur à problèmes, mais en fait elle est très pratique à partir du moment où on sait l'utiliser.

Notamment, ceux qui utilisent les jointures se plaignent qu'on ne peut récupérer les lignes où la réfèrence est nulle, c'est simplement parce qu'ils utilisent LEFT JOIN au lieu de RIGHT JOIN, mais ça c'est l'objet d'un autre chapitre. ^^


Les valeurs NULL, comme je vous le disais, sont spéciales. Par exemple, on ne peut pas les comparer. Pour comprendre ce principe, créons une table exemple :

Code : SQL
1
2
CREATE TABLE ex_null ( id INT AUTO_INCREMENT, points INT DEFAULT NULL, PRIMARY KEY ( id ) );
INSERT INTO ex_null ( points ) VALUES ( 135 ), ( 3484 ), ( DEFAULT ), ( DEFAULT ), ( 0 ), ( DEFAULT );


Dans cette table, les NULL représentent ceux qui n'ont jamais gagné ni perdu de points. Les 0 représentent ceux qui ont déjà gagné des points, mais les ont reperdus.

Un autre façon de faire cette table aurait été d'ajouter une colonne "a_deja_joue", mais elle est totalement inutile dans le sens où un NULL nous permet d'avoir cette information plus facilement sans colonne supplémentaire.

Essayons de récupérer les lignes de ceux qui n'ont jamais joué:

Code : SQL
1
SELECT id, points FROM ex_null WHERE points = NULL;

Image utilisateur


Euh... o_O MySQL est devenu bigleu ?? :waw:


Non, c'est juste que les NULL ne peuvent pas être comparés à l'aide du signe "=". Et encore, MySQL est gentil : tout autre SGBDR aurait renvoyé une erreur (ou le devrait, tout comme MySQL).

Pour savoir si une valeur est nulle, il faut utiliser l'opérateur IS NULL :

Code : SQL
1
SELECT id, points FROM ex_null WHERE points IS NULL;

Image utilisateur


C'est déjà mieux, non ? :p :)

Attention également aux opérations comprenant des valeurs nulles : 1 + NULL = NULL en SQL !
A noter les opérations avec OR : x OR NULL = x SAUF SI x = NULL ou x = 0 !

Les fonctions de traitement des valeurs nulles

COALESCE



Fonction très pratique : COALESCE prend une liste d'arguments aussi longue que l'on veut (pas trop quand même :p ), et renvoie la première valeur non nulle passée en argument :

Code : SQL
1
SELECT COALESCE(NULL, 0);

Renvoie 0.

Donc dans notre table d'essai, pour renvoyer 0 au lieu de NULL, on pourrait faire comme ça :

Code : SQL
1
SELECT id, COALESCE(points, 0) FROM ex_null;

Image utilisateur


Un exemple de la praticité de la fonction COALESCE :

Code : SQL
1
SELECT id, COALESCE(points, 'N''a jamais joue') AS points FROM ex_null;

Image utilisateur


Essayez donc d'obtenir un tel résultat si facilement avec une colonne "a_deja_joue" supplémentaire. ;) :)

IFNULL



IFNULL est une fonction assez... spéciale et plutôt compliquée à comprendre au début, mais rassurez-vous : on s'y fait tous. :p :)

IFNULL prend deux paramètres.

Si le premier paramètre est NULL, alors le deuxième paramètre est renvoyé.
Si le premier paramètre n'est pas NULL, alors c'est lui-même qui est renvoyé.

Compris ? :p

Relisez ça une paire de fois, et passez à la suite une fois que vous serez sûr d'avoir compris. :)

On va simuler une colonne a_deja_joue qui vaudra 0 si les points sont égaux à NULL, sinon 1.

Pour cela, on va commencer par utiliser IFNULL(points, 0)

Code : SQL
1
SELECT id, IFNULL(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Ainsi, si points est NULL, on aura 0, sinon on aura [points].

Pour le 0, c'est bon, mais nous, on veut 1, on ne veut pas points, car si points vaut 0 (comme l'enregistrement ayant pour id 5), notre système ne fonctionnera pas. On va donc diviser le résultat du IFNULL par COALESCE(points, 1). Ainsi on aura soit 1 (points <> 0 => points/points = 1), soit 0 (points = NULL => 0 / 1 = 0), soit NULL (points = 0 => 0 / 0 = NULL en SQL).

Code : SQL
1
SELECT id, IFNULL(points, 0) / COALESCE(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Ici, on peut améliorer un truc : comme vous le voyez, on obtient 1.0000 et 0.0000, pas super joli, pour obtenir 1 et 0 il suffit d'utiliser l'opérateur DIV vu au second chapitre. :)

Code : SQL
1
SELECT id, IFNULL(points, 0) DIV COALESCE(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Il reste un tout petit problème : les NULL (points = 0) doivent être transformés en 1. Pour cela, évidemment, rien de plus simple, il suffit d'utiliser, une fois de plus, la fonction COALESCE qui englobera cette fois toute la division :

Code : SQL
1
SELECT id, points, COALESCE(IFNULL(points, 0) DIV COALESCE(points, 1), 1) AS a_deja_joue FROM ex_null;

Image utilisateur


Assez sympa non ? Bon j'admets que ce n'était peut-être pas super super simple à comprendre, mais en y allant étape par étape, ça a du bien se passer, enfin j'espère. :)

En fait, il existe une méthode beaucoup plus simple pour obtenir cela, l'inconvénient, c'est qu'elle n'est valable qu'avec MySQL. :( Je vous déconseille vraiment de l'utiliser, surtout si vous faites des calculs à base du résultat, voici cette autre requête :

Code : SQL
1
SELECT id, points IS NULL AS a_deja_joue FROM ex_null;


Dans le prochain chapitre, nous verrons une méthode plus "standard" pour obtenir le même résultat, ne vous inquiétez pas : vous n'êtes pas condamné à utiliser IFNULL qui en fait n'est que très rarement utilisé et assez peu pratique... ^^

Le système de classement en une seule requête !

Vous vous souvenez du système de classement vu dans le chapitre précédent ? (j'espère que oui sinon mon enseignement ne serait pas d'une grande utilité :D ). Voici les requêtes que je vous avais données :

Code : SQL
1
2
SET @place = 0;
SELECT @place := @place + 1 AS place, pseudo, points FROM joueurs ORDER BY points DESC;


Et bien grâce aux fonctions que nous venons de voir, nous pouvons maintenant tout rassembler sur une seule ligne !

En fait, ça ne sert à strictement rien et ça ralentit un peu la requête, mais c'est toujours intéressant de le savoir car peut-être que vous serez confrontés à des cas où vous serez obligés d'utiliser la technique suivante :

Code : SQL
1
SELECT @place := COALESCE(@place, @place := 0) + 1 AS place, pseudo, points FROM joueurs ORDER BY points DESC;

Image utilisateur


Pratique non ? On peut également vérifier facilement si une variable a déjà été déclarée grâce à la fonction IFNULL. Comme vous le constatez, les fonctions de traitement des valeurs NULL sont relativement pratiques couplées aux variables utilisateur. Elles permettent aussi de compacter les requêtes et d'éviter un CASE (on verra ça dans le prochain chapitre) ou un IF (prochain chapitre également :p ), bien que parfois, ces fonctions (particulièrement IFNULL) font tout sauf compacter la requête. :D :p

Voilà, j'espère que ça vous a plu et que vous vous rendez compte de l'erreur que font les développeurs qui préfèrent travailler avec des chaînes vides plutôt qu'avec des valeurs nulles puis qui doivent se farcir des IF au lieu d'un simple COALESCE ou IFNULL. :D

Les conditions

Les conditions SQL ne sont pas forcément importantes pour l'optimisation mais sont extrêmement pratiques pour obtenir des données tirées d'autres données très rapidement. Elles permettent de renvoyer une valeur si une expression est vraie, ou une autre valeur si elle est fausse...

Enfin, je vous laisse découvrir ça, vous vous rendrez vite compte de leur utilité. ;) :)

Des conditions en SQL ? Différences entre MySQL et la norme

La norme SQL prévoit ce qu'on appelle des structures conditionnelles qui permettent de dire "SI telle valeur vaut ça, faire ça, sinon si cette valeur vaut ça, faire ça, sinon faire ça".

Ce n'est bien sûr qu'un exemple, mais c'est le principe. Une structure conditionnelle permet d'énoncer... Des conditions. :p

Dans MySQL, il existe 4 structures conditionnelles :



Les deux dernières structures peuvent très facilement être obtenues à partir des deux premières et sont plus limitées. En fait, elles sont spécifiques à MySQL et n'existent pas dans la norme.

Il est notamment déconseillé d'utiliser IF car si un jour vous passez à PostGreSQL (par exemple), vous allez devoir restructurer toutes vos requêtes... :(

IFNULL, même s'il n'est pas repris par la norme, est implémenté dans la plupart des SGBDR (notamment MySQL, PostGreSQL et SQL Server), cela est donc moins grave si vous l'utilisez, mais c'est déconseillé quand même...

Utilisation de CASE

CASE est la structure conditionnelle la plus répandue parmis les SGBDR. Et c'est également la plus complète ! Les autres structures sont toutes dérivées de celle-ci.
Pour toutes les structures conditionnelles suivantes, je vous montrerais à chaque fois le rapport entre la structure et CASE.

Bon alors comment on l'utilise, ce CASE ?


C'est assez simple, voici tout d'abord une structure générale :

Code : SQL
1
2
3
4
5
6
CASE [colonne]
WHEN condition THEN valeur
WHEN condition THEN valeur
[...]
ELSE valeur
END


Bon, peut-être qu'à première vue, comme ça, ça ne vous parle pas trop, mais avec les exemples ça rentrera tout seul. ;) :)

Faites attention à ne pas oublier le END à la fin du CASE, sinon vous aurez droit à une belle erreur d'exécution ! :colere2:


Voici un premier exemple :

Code : SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
SELECT @a, CASE
        WHEN @a > 0 THEN 'positif'
        WHEN @a < 0 THEN 'negatif'
        WHEN @a = 0 THEN 'nul'
        ELSE 'NULL'
        END AS signe_a;
SET @a = -5;
SELECT @a, CASE
        WHEN @a > 0 THEN 'positif'
        WHEN @a < 0 THEN 'negatif'
        WHEN @a = 0 THEN 'nul'
        ELSE 'NULL'
        END AS signe_a;

Image utilisateur


Je crois que l'exemple se passe de commentaire : le code veut dire ce qu'il veut dire. :p

Imaginons maintenant un autre cas : on fait un script de news et on a une colonne dans la table des news qui s'appelle 'validee' et qui indique si la news a été validée par un admin ou pas.

Dans le panel d'administration, on affiche toutes les news dans un tableau, et dans la colonne "Validée ?", on aimerait indiquer "validée", ou "en attente de validation" plutôt que 0 ou 1...

Rien de plus simple avec CASE ! Voici une table fictive :

Code : SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CREATE TABLE news (
id int NOT NULL AUTO_INCREMENT,
titre varchar(100) NOT NULL,
validee tinyint NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);

INSERT INTO news (titre, validee) VALUES ('news 1', 1);
INSERT INTO news (titre, validee) VALUES ('news 2', 0);
INSERT INTO news (titre, validee) VALUES ('news 3', 0);
INSERT INTO news (titre, validee) VALUES ('news 4', 2);
INSERT INTO news (titre, validee) VALUES ('news 5', 1);
INSERT INTO news (titre, validee) VALUES ('news 6', 0);


Essayez de trouver une requête qui renverra :


Quand vous penserez avoir trouvé la requête, comparez votre code au mien :

Secret (cliquez pour afficher)
Image utilisateur

Code : SQL
1
SELECT id, titre, CASE WHEN validee = 1 THEN 'Validee' WHEN validee = 0 THEN 'En attente de validation' ELSE 'Etat inconnu' END AS validee_txt FROM news;


Bon, normalement c'était pas trop dur. :D

Oui mais attend, tantôt en nous montrant la structure de base, j'ai vu qu'elle commençait comme ça : CASE [colonne] WHEN ... A quoi correspond ce [colonne] ?


Bien vu, en fait l'exemple que je viens de vous montrer peut être simplifié grâce à ce [colonne]. Comme un exemple vaut mieux qu'un long discours, voici le code qu'on aurait pu aussi utiliser :

Code : SQL
1
SELECT id, titre, CASE validee WHEN 1 THEN 'Validee' WHEN 0 THEN 'En attente de validation' ELSE 'Etat inconnu' END AS validee_txt FROM news;

Image utilisateur


Pratique aussi non ? Le seul problème avec cette syntaxe c'est qu'elle ne s'applique pas à tous les cas, par exemple notre premier exemple (savoir si @a était positif, négatif, nul (0) ou NULL) ne pourrait utiliser cette syntaxe car on ne peut pas mettre le signe ">" ou "<".

Vous suivez toujours ? Tant mieux parce qu'on a fait le plus dur. :D :p

Les autres structures conditionnelles

Comme je vous l'ai dit, il existe trois autres structures conditionnelles en dehors de CASE en MySQL : IF, NULLIF et IFNULL.

Nous avons déjà vu l'utilité de IFNULL mais je vais en reparler juste pour vous montrer le lien avec CASE et la facilité de ce dernier.

Une alternative simplifiée : IF



IF est en fait une fonction. Voici comment on l'utilise :

Code : SQL
1
SELECT IF(condition, operation_si_vrai, operation_si_faux);


Comme vous le constatez, IF est beaucoup plus limité que CASE, voici comment on pourrait reproduire IF dans un CASE :

Code : SQL
1
SELECT CASE WHEN condition THEN operation_si_vrai ELSE operation_si_faux END;


Vous vous souvenez de ce qu'on a vu au chapitre précédent ? La table ex_null qui contenait des scores ou NULL si le joueur n'avait joué aucune partie...

Et bien le IF se prête bien à cette situation, nous avions utilisé cette requête :

Code : SQL