Vous êtes sur la page 1sur 6

MySQL: la commande SELECT

Savoir interroger sa base


aura comme rsultat: NOM L'criture de requtes est tout un art ds lors que la complexit d'une base de donnes devient plus ou moins Jean grande. Les mauvais temps de rponses de beaucoup de Martin sites proviennent souvent de requtes mal formes et/ou non optimales. Bien souvent une simple rcriture de cellesci amliore considrablement la ractivit d'un site sans avoir mettre en oeuvre toute une srie de CONCAT() technologies palliatives tels les caches par exemple. Nous allons donc regarder ici de plus prs cette fameuse La concatnation permet d'agrger plusieurs champs en un seul. Normallement, en SQL cet oprateur est commande SELECT qui en effraye plus d'un. reprsent ainsi || mais trs peu de SGBD l'implmentent. MySQL nous fournit la fonction CONCAT(). L'utilisation de Syntaxe de SELECT concat est trs intressante dans le cas o l'on doit afficher des informations synthtiques plutt que de Le cas SELECT * raliser l'opration soismme l'intrieur d'un script PHP: de manire gnrale, tout ce qui pourra tre ralis En thorie dconseill car SELECT * demande de charger l'intrieur d'une requte sera toujours prfrable une tous les champs d'un enregistrement, son utilisation est solution faisant appel un traitement ultrieur par un parfaitement justifiable dans le cas ou la taille totale de ce langage de script y compris PHP. qui sera slectionn est acceptable. Une clause WHERE limitant le nombre d'enregistrements candidats pourra ainsi En reprenant la table table1, le query suivant: justifier de l'usage de SELECT *.

SELECT DISTINCT

SELECT CONCAT(NOM,'',PRENOM) FROM table1;

DISTINCT permet d'liminer les doublons dans une rponse, en effet par dfaut, un SELECT seul est aura comme rsultat: identique un SELECT ALL. Soit la table table1: table1 NOM Dupont Durand Laurier Jean Martin Jean PRENOM CONCAT(NOM,'',PRENOM) DupontJean DurandMartin LaurierJean

CONCAT() AS
Le query suivant: SELECT PRENOM FROM table1; L'utilisation de la fonction CONCAT() donne pour rsultat un champ dont le nom est celui de l'opration ralise (voir cidessus). Pour des raisons pratiques videntes il est prfrable de pouvoir nommer explicitement le champ rsultant. On utilise pour cela l'oprateur AS qui permet de dfinir un alias pour le champ. En reprenant l'exemple prcdent, nous pourrions crire le query ainsi: NOM Jean Martin Jean Identity et le query suivant: SELECT DISTINCT PRENOM FROM table1; DupontJean DurandMartin LaurierJean SELECT CONCAT(NOM,'',PRENOM) AS Identity FROM table1; qui aurait comme rsultat:

aura comme rsultat:

01/22/03

MySQL: la commande SELECT


La clause WHERE
La clause WHERE permet de raliser un test logique sur la condition qui la suit. Un rsultat est obtenu lorsque la condition value est VRAIE. Une condition utilise les oprateurs de comparaison et les oprateurs logiques dans le but de restreindre une recherche. Soit la table table2: table3 table2 ID 1 2 4 7 8 Dupont Durand Laurier Gombart Androux NOM Jean Martin Jean Henry Michel le query suivant: Le query suivant: SELECT * FROM table2 WHERE id=7; SELECT * FROM table3 ORDER BY NOM; est identique au query: SELECT * FROM table3 ORDER BY NOM ASC; NOM Gombart PRENOM Henry ID 8 alors que le query suivant: SELECT * FROM table2 WHERE PRENOM='Jean'; 1 2 7 4 et le query: NOM Dupont Laurier Jean Jean aura comme rsultat: ID et le query suivant: SELECT * FROM table1 WHERE ID > 0; 4 7 2 1 8 aura comme rsultat la table en son entier. Laurier Gombart Dupont Dupont Androux NOM Jean Henry Alain Jean Michel PRENOM PRENOM SELECT * FROM table3 ORDER BY NOM DESC,PRENOM ASC; Dupont Dupont Gombart Laurier NOM Androux Jean Alain Henry Jean PRENOM Michel et aura comme rsultat: PRENOM 1 2 4 7 8 ID Dupont Dupont Laurier Gombart Androux NOM Jean Alain Jean Henry Michel PRENOM

La clause ORDER BY
Jusqu' prsent les rsultats retourns n'taient pas forcment classs. La clause ORDER BY permet de spcifier un ordre croissant ou dcroissant par rapport un ou plusieurs champs. Par dfaut une clause ORDER BY champ1 est idantique ORDER BY champ1 ASC. Si l'on prend comme exemple la table table3 suivante:

aura pour rsultat: ID 7

aura comme rsultat: ID 1 4

01/22/03

MySQL: la commande SELECT


La clause GROUP BY MIN()
La clause GROUP BY permet de regrouper des valeurs La fonction MIN() renvoie la valeur minimum d'une srie. d'un champ en vue d'un traitement statistique. Cette Appliqu la table table4 le query suivant: clause n'est donc pratiquement jamais utilise seule mais en conjonctions avec des fonctions que nous allons tudier SELECT LOGIN,MIN(SCORE) AS MINI cidessous. FROM table4 GROUP BY LOGIN ORDER BY MINI ASC;

COUNT()
aura comme rsultat: La fonction COUNT() permet comme son nom l'indique de compter le nombre de lignes. Utilise en association avec la clause GROUP BY elle permet de compter les lignes satisfaisant un critre et regroupes selon les valeurs d'un champ. Soit la table table4 stockant les scores d'un jeu en ligne pour chaque utilisateur: table4 ID 1 2 3 4 5 alain alain alain pitou pitou LOGIN 12 14 9 17 14 SCORE LOGIN alain pitou 9 14 MINI

MAX()
Rciproque de la fonction MIN, la fonction MAX() renvoie la valeur maximum d'une srie. Appliqu la table table4 le query suivant: SELECT LOGIN,MAX(SCORE) AS MAXI FROM table4 GROUP BY LOGIN ORDER BY MAXI DESC; aura comme rsultat: LOGIN pitou alain 17 14 MAXI

Nombre de parties par joueur: SELECT LOGIN,COUNT(*) AS nbGAMES FROM table4 GROUP BY LOGIN; aura pour rsultat: LOGIN alain pitou 3 2 nbGAMES

SUM()
La fonction SUM() calcule la somme d'une srie. Si l'on dsire partir de la table table4 connatre le nombre total de points marqus par chacun des joueurs, le query suivant: SELECT LOGIN,SUM(SCORE) AS TOTAL FROM table4 GROUP BY LOGIN ORDER BY TOTAL DESC;

AVG()

la fonction AVG() permet de calculer une moyenne. Ainsi, le query suivant: aura comme rsultat: SELECT LOGIN,AVG(SCORE) AS MOY FROM table4 GROUP BY LOGIN ORDER BY MOY DESC; aura comme rsultat: LOGIN pitou alain 15.5000 11.6667 MOY LOGIN alain pitou 35 31 MAXI

01/22/03

MySQL: la commande SELECT


Oprateurs divers BETWEEN
aura comme rsultat: EMAIL SCORE

alain@wanadoo.fr 12 L'oprateur BETWEEN dans une clause WHERE permet alphonse@free.fr 14 de slectionner les lignes dont la valeur d'un champ est inclus entre 2 bornes. BETWEEN est equivalent borne1 <= valeur <= borne2. L'oprateur sait travailler avec des Le caractre % signifiant "n'importe quel nombre de chaines de caractres. En reprenant la table table4: caractres" table4 ID 1 2 3 4 5 alain alain alain pitou pitou LOGIN 12 14 9 17 14 aura comme rsultat: EMAIL alain@wanadoo.fr charic@wanadoo.be pitou@wanadoo.fr 12 9 5 SCORE SCORE SELECT EMAIL,SCORE FROM table5 WHERE EMAIL LIKE '%wanadoo%' ORDER BY EMAIL; Recherche des emails contenant 'wanadoo':

Le query suivant: SELECT LOGIN,SCORE FROM table4 WHERE SCORE BETWEEN 14 AND 17 ORDER BY SCORE DESC; aura pour rsultat: LOGIN pitou alain pitou 17 14 14 SCORE

Recherche des adresses finissant par '.fr': SELECT EMAIL,SCORE FROM table5 WHERE EMAIL LIKE '%.fr' ORDER BY EMAIL;

LIKE
L'oprateur LIKE permet de raliser une comparaison partielle. Soit la table table5: table5 EMAIL alain@wanadoo.fr charic@wanadoo.be buzuk@infonie.fr charle@arnaq.com pitou@wanadoo.fr alphonse@free.fr 12 9 11 17 5 14 SCORE

aura comme rsultat: EMAIL alain@wanadoo.fr alphonse@free.fr buzuk@infonie.fr pitou@wanadoo.fr 12 14 11 5 SCORE

La clause LIMIT
Jusqu' prsent le nombre de rsultats renvoys par une requte n'tait limit que par les conditions. Dans certains cas, une requte mme bien spcifie peut engendrer un nombre de rsultats important, ce qui peut tre gnant lors de l'affichage (cas d'une liste par exemple). Bien que nonportable (PostGreSQL la gre depuis peu) la clause LIMIT peut vous simplifier grandement la vie.

Recherche des emails commenant par 'al': SELECT EMAIL,SCORE FROM table5 WHERE EMAIL LIKE 'al%';

01/22/03

MySQL: la commande SELECT


La Syntaxe de LIMIT est la suivante: LIMIT debut, nombre_de_lignes

SELECT multitables

Jusqu' prsent nous n'avons utilis la commande SELECT qu'avec une seule table. La puissance du En reprenant la table table5 de la page prcdente, le langage SQL revt tout son intrt lorsque l'on doit query suivant: manipuler des informations provenant de plusieurs tables et que ces informations sont relies entre elles de faon SELECT * FROM table5 cohrente. LIMIT 0, 4; Soit les deux tables: aura pour rsultat: ID EMAIL alain@wanadoo.fr charic@wanadoo.be buzuk@infonie.fr charle@arnaq.com 12 9 11 17 LEVEL et le query suivant: 1 SELECT * FROM table5 LIMIT 4, 4; 2 3 4 aura pour rsultat: EMAIL pitou@wanadoo.fr alphonse@free.fr 5 14 SCORE Si nous voulons afficher la liste des joueurs avec le niveau qu'ils ont atteint, nous effectuerons le query suivant: SELECT JOUEUR.LOGIN,LEVEL.NIVEAU FROM JOUEUR, LEVEL WHERE JOUEUR.LEVEL_ID=LEVEL.ID; ORDER BY LEVEL.ID DESC; ID Pilote Capitaine Commandant Amiral NIVEAU SCORE 1 2 3 4 alain pitou manu gg JOUEUR LOGIN 1 2 4 1 LEVEL_ID

La clause HAVING

La clause HAVING applique une condition supplmentaire sur un ou plusieurs champs lists dans la commande qui aura pour rsultat: SELECT. Cette clause s'applique juste avant l'envoi du rsultat et n'est pas interprte par l'optimiseur, il faut donc LOGIN eviter de faire un query juste avec HAVING sans manu restriction sur les conditions. pitou Soit le query suivant: alain SELECT EMAIL,MAX(SCORE) AS BESTSCORE FROM table5 GROUP BY EMAIL HAVING BESTSCORE > 15; gg

NIVEAU Amiral Capitaine Pilote Pilote

Utilisation de AS
aura pour rsultat: EMAIL charle@arnaq.com 17 BESTSCORE L'utilisation de la syntaxe table.champ pour accder un champ peut entraner des problmes de lisibilit dus l'criture de queries un peu longs. En affectant un alias au nom des tables l'aide de AS on peut notablement raccourcir l'criture du query prcdent.

01/22/03

MySQL: la commande SELECT


Le query devient: SELECT J.LOGIN,L.NIVEAU FROM JOUEUR AS J, LEVEL AS L WHERE J.LEVEL_ID=L.ID; ORDER BY L.ID DESC; et dont le rsultat sera identique au prcdent. Dans le cas que nous venons de voir, la relation entre les tables est dite relation 1 > 1: chaque enregistrement de la table JOUEUR correspond un enregistrement de la table LEVEL. Nous allons maintenant tudier un cas particulier qui est celui o l'on recherche non pas les valeurs prsentes dans une table, mais au contraire des valeurs absentes. La jointure LEFT JOIN va nous permettre de raliser cette opration. Les exemples multitables prcdents constituent ce que l'on nomme une jointure croise. Il suffit de slectionner les enregistrements en vrifiant l'galit du contenu d'un champ de la premire table et d'un champ de la seconde table.

LEFT JOIN...ON

Nous allons maintenant regarder de plus prs le cas des relations 1 > n, qui signifient qu' tout enregistrement Si l'on reprend la table LEVEL et que l'on effectue le query d ' u n e t a b l e A c o r r e s p o n d e n t 1 o u p l u s i e u r s suivant: enregistrements dans une table B. SELECT NIVEAU,LOGIN FROM LEVEL AS L Soit la table SCORE stockant les rsultats des parties de LEFT JOIN JOUEUR ON L.ID=JOUEUR.LEVEL_ID; chacun des joueurs. Chaque joueur peut avoir fait une ou plusieurs parties. On sait quel joueur appartient un score en stockant l'identifiant du joueur concern ( savoir son nous aurons comme rsultat: ID dans la table JOUEUR). Cet identifiant sera stock dans le champ PLAYER_ID. NIVEAU LOGIN SCORE ID 1 2 3 4 5 6 7 3 2 1 3 2 3 4 PLAYER_ID 12 11 10 14 13 17 9 Nous remarquons que pour le niveau Commandant, la colonne LOGIN est vide. Si nous dsirons rpondre la question 'Quel niveau n'est pas affect au moins un joueur?' nous crivons le query suivant: SELECT NIVEAU FROM LEVEL AS L LEFT JOIN JOUEUR ON L.ID=JOUEUR.LEVEL_ID WHERE LOGIN IS NULL; POINTS pilote pilote Capitaine Commandant Amiral manu alain gg pitou

Le query suivant: SELECT J.LOGIN,SUM(S.POINTS) AS TSCORE FROM JOUEUR AS J, SCORE AS S WHERE J.ID=S.PLAYER_ID; ORDER BY TSCORE DESC;

qui aura pour rsultat: NIVEAU

aura pour rsultat: LOGIN manu pitou alain gg 43 24 10 9 TSCORE

Commandant

KDO kdo@zephpmag.com

01/22/03