Vous êtes sur la page 1sur 39

1Z C1 CW m m Z

Par Frdric BROUARD



Le simple (?) SELECT et les fonctions SQL

Dans le prcdent article nous avons vu lhistorique de SQL et
ses diffrentes composantes. Nous entrons maintenant dans le
vif du sujet, en nous intressant au simple SELECT.
Simple ? Pas si sr... Dans le dernier document normatif de
lISO, la syntaxe de la commande SELECT, est dcrite en plus
de 300 pages Cest pourquoi nous nous permettons de mettre en
doute la simplicit de la commande SELECT !

1) La commande SELECT

Le SELECT est la commande de base du SQL destine extraire
des donnes dune base ou calculer de nouvelles donnes
partir dexistantes
Voici la syntaxe gnrale d'une commande SELECT :

SELECT [DISTINCT ou ALL] * ou liste de colonnes
FROM nom de table ou de la vue
[WHERE prdicats]
[GROUP BY ordre des groupes]
[HAVING condition]
[ORDER BY ] liste de colonnes

NOTA : dans cette syntaxe, les mots clef du SQL sont en
majuscule droite, les paramtres en minuscule italique et
entre crochets on trouve les parties optionnelles
En fait l'ordre SQL SELECT est compos de 6 clauses dont 4
sont optionnelles. Clauses de l'ordre SELECT :

SELECT Spcification des colonnes du rsultat
FROM Spcification des tables sur lesquelles porte l'ordre
WHERE
Filtre portant sur les donnes (conditions remplir
pour que les lignes soient prsentes dans le rsultat)
GROUP
BY
Dfinition d'un groupe (sous ensemble)
HAVING
Filtre portant sur les rsultats (conditions de
regroupement des lignes)
ORDER
BY
Tri des donnes du rsultat

NOTA : La plupart du temps, la difficult rside dans la
comprhension de la diffrence entre le filtre WHERE et le
filtre HAVING. Disons plus pragmatiquement que le filtre WHERE
permet de filtrer les donnes des tables tandis que le filtre
HAVING permet de filtrer les donnes du rsultat.

REMARQUE : pour spcifier une valeur littrale il faut
l'entourer de guillemets simples.

Un premier exemple basique : exemple 1
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
WHERE TIT_CODE = M.
CLI_NOM CLI_PRENOM
------- ----------
DUPONT Alain
MARTIN Marc
BOUVIER Alain
DUBOIS Paul
DREYFUS Jean
FAURE Alain
PAUL Marcel
DUVAL Arsne
PHILIPPE Andr
CHABAUD Daniel
BAILLY Jean-Franois
...
Permet de trouver les noms et prnoms des clients dont le
titre est M. (monsieur).
NOTA : comme tous les paramtres prendre sous forme de
littraux doivent tre exprimes entours d'apostrophes
(simple ctes), il faut ddoubler un tel caractres s'il
s'avre prsent dans la chane utilis.

1.1) l'oprateur * (toile)

Le caractre * (toile) rcupre toutes les colonnes de la
table prcise dans la clause FROM de la requte. Juste
aprs le mot clef SELECT, on prcise les colonnes de la table
qui doivent tre prsentes dans la rponse. Lutilisation du
caractre toile ramne toutes les colonnes de la table dans
la rponse. Dans le cas contraire il faut expressment nommer
chacune des colonnes et les sparer par des virgules.

exemple 2
SELECT *
FROM T_CLIENT
WHERE TIT_CODE = 'M.'
CLI_ID TIT_CODE CLI_NOM CLI_PRENOM CLI_ENSEIGNE
------- -------- -------- ---------- ------------
1 M. DUPONT Alain NULL
2 M. MARTIN Marc Transports MARTIN & fils
3 M. BOUVIER Alain NULL
4 M. DUBOIS Paul NULL
5 M. DREYFUS Jean NULL
6 M. FAURE Alain Boulangerie du march
11 M. PAUL Marcel Cie Internationale des
Machines Electromcaniques
12 M. DUVAL Arsne NULL
13 M. PHILIPPE Andr NULL
16 M. CHABAUD Daniel NULL
...
Notons tout de suite la prsence plusieurs reprises du mot
clef "NULL" dans la colonne CLI_ENSEIGNE. Non il ne s'agit pas
d'une enseigne particulire, mais simplement de l'absence
d'information. Nous verrons que l'absence d'information, c'est
le marquer "NULL" qui diffre de la chane de caractre vierge
("") ou encore du zro.

1.2) l'oprateur DISTINCT (ou ALL)

Lorsque le moteur construit la rponse, il rapatrie toutes les
lignes correspondantes, gnralement dans lordre ou il les
trouve, mme si ces dernires sont en double, c'est dire
qu'il rcupre toutes les lignes (ALL par dfaut). Cest
pourquoi il est souvent ncessaire dutiliser le mot clef
DISTINCT qui permet dliminer les doublons dans la rponse

exemple 3
SELECT CLI_PRENOM
FROM T_CLIENT
WHERE TIT_CODE = 'M.'
CLI_PRENOM
----------
Alain
Marc
Alain
Paul
Jean
Alain
Marcel
Arsne
Andr
Daniel
...
SELECT distinct CLI_PRENOM
FROM T_CLIENT
WHERE TIT_CODE = 'M.'
CLI_PRENOM
----------
Alain
Alexandre
Andr
Arnaud
Arsne
Bernard
Christian
Christophe
Daniel
Denis
...

1.3) Oprateur AS

Vous pouvez rajouter autant de colonnes que vous le dsirez en
utilisant le mot clef AS. En principe loprateur AS sert
donner un nom de nouvelles colonnes cres par la requte.
exemple 5
SELECT CLI_NOM as NOM, 'homme' as SEXE
FROM T_CLIENT
WHERE TIT_CODE = 'M.'
NOM SEXE
------- -----
DUPONT homme
MARTIN homme
BOUVIER homme
DUBOIS homme
DREYFUS homme
FAURE homme
PAUL homme
DUVAL homme
PHILIPPE homme
CHABAUD homme
...

1.4) Oprateur de concatnation

L'oprateur || (double barre verticale) permet de concatner
des champs de type caractres
exemple 6
SELECT TIT_CODE || ' ' || CLI_PRENOM
|| ' ' || CLI_NOM as NOM
FROM T_CLIENT
NOM
-----------------------
M. Alain DUPONT
M. Marc MARTIN
M. Alain BOUVIER
M. Paul DUBOIS
M. Jean DREYFUS
M. Alain FAURE
M. Paul LACOMBE
Melle. Evelyne DUHAMEL
Mme. Martine BOYER
M. Martin MARTIN
...
Nanmoins on trouve dans certains SGBDR le + comme oprateur
de concatnation, comme la fonction CONCAT.

1.5) Oprateur mathmatiques de base

On, peut utiliser les oprateurs mathmatiques de base pour
combiner diffrentes colonnes (,+,-, *, /,).
exemple 7
SELECT CHB_ID, TRF_CHB_PRIX * 1.206 AS
TARIF_TTC
FROM TJ_TRF_CHB
WHERE TRF_DATE_DEBUT = '2001-01-01'
CHB_ID TARIF_TTC
------ ---------
1 424,51
2 482,40
3 617,47
4 424,51
5 463,10
6 482,40
7 424,51
8 540,29
9 482,40
10 617,47
...

1.6) Particularit du "FROM"

Il est possible de surnommer une table dans la clause FROM,
dans ce cas, la syntaxe de la partie FROM de la commande
SELECT est la suivante :

FROM nom_de_table ou nom_de_la_vue surnom

Nous verrons dans quel cas ce renom est ncessaire ou
obligatoire.
NOTA : certains auteurs prfre utiliser le mot d'alias que
nous rejetons car il indique souvent un autre concept, ou de
synonyme, que nous acceptons de manire timore...

1.7) Utilisation du caractre double quote (guillemet)

Lorsquun nom dun lment dune base de donnes (table,
colonne par exemple) est identique un mot clef du SQL, il
convient de lentourer de guillemets (double quote). En
principe, les mots rservs du SQL sont dconseill pour
nommer des objets du modle physique de donnes...
Imaginons une table de nom JOIN, compose des champs suivants
:
NOM SELECT DATE NOT
------- ------ ------- ---
DURAND Oui 1999-11-12 F
DUVAL Non 1998-01-17 M
Exemple 8 : nous dsirons slectionner les colonnes SELECT et
DATE lorsque la colonne NOT vaut F...
SELECT SELECT,
DATE
FROM JOIN
WHERE NOT = 'F'
ERREUR !
SELECT "SELECT",
"DATE"
FROM "JOIN"
WHERE "NOT" = 'F'
Correct : on entoure les mots clefs du SQL
par des doubles ctes
Cela est aussi ncessaire lorsque le nom (d'une colonne ou
d'une table) est compos de caractres particuliers tels que
les blancs ou autres, ce qui est a viter.
REMARQUE : les noms des identifiants d'objet de base de
donnes doivent tre crit dans le jeux de caractres
restreint suivant : [A..Z] + [a..z] + [0..9] + [ _ ]. Ils ne
doivent pas commencer par un chiffre et sont insensible la
casse (indiffrence entre majuscule et minuscule).

2) Clause ORDER BY


ORDER BY colonne1 | 1 [ASC ou DESC ] [, colonne2 | 2 [ASC ou
DESC ] ...

Cette clause permet de dfinir le tri des colonnes de la
rponse, soit en prcisant le nom littral de la colonne, soit
en prcisant son n d'ordre dans l'numration qui suit le mot
clef SELECT. ASC spcifie lordre ascendant et DESC lordre
descendant du tri. ASC ou DESC peut tre omis, dans ce cas
c'est l'ordre ascendant qui est utilis par dfaut.
Bien que la clause ORDER BY ne soit pas ncessaire, il est
souvent utile de trier la rponse en fonction des colonnes. En
revanche le temps de rponse s'en ressent souvent.
Pour spcifier l'ordre de tri, on doit placer les noms des
colonnes spares par des virgules juste aprs le mot clef
"ORDER BY", dans l'ordre voulu.. On peut aussi utiliser le
rang de chaque colonne dans l'ordre spcifi dans la clause
SELECT.
Attention : le tri est un tri interne, il ne faut donc placer
dans cette clause que les noms des colonnes prsentes dans la
clause SELECT.
Souvent, le fait de placer DISTINCT suffit, en gnral,
tablir un tri puisque le moteur doit se livrer une
comparaison des lignes mais ce mcanisme n'est pas garantit
car ce tri seffectue dans un ordre non contrlable qui peut
varier dun serveur lautre.
exemple 9
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
ORDER BY CLI_NOM, CLI_PRENOM
ou
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
ORDER BY 1, 2
CLI_NOM CLI_PRENOM
-------- ----------
AIACH Alexandre
ALBERT Christian
AUZENAT Michel
BACQUE Michel
BAILLY Jean-Franois
BAVEREL Frdric
BEAUNEE Pierre
BENATTAR Bernard
BENATTAR Pierre
BENZAQUI Jol
...
REMARQUE : les marqueur NULL sont situes en premier dans
l'ordre ainsi tablit.
NOTA : Un problme, qui nest pas rsolu, est de pouvoir
choisir lordre des colonnes de la rponse. Sur certains
serveurs cela peut tre obtenu en plaant les noms des
colonnes obtenir dans lordre o lon veut les voir
apparatre dans la clause SELECT, mais cette possibilit n'est
jamais garantie...
ATTENTION : la clause ORDER BY est la dernire clause de tout
ordre SQL et ne doit figurer qu'une seule fois dans le SELECT,
mme s'i l existe des requtes imbriques ou un jeu de
requtes ensemblistes

3) La clause WHERE


WHERE prdicats

Le prdicat doit contenir nimporte quelle expression logique
renvoyant une valeur vrai. Ainsi, une requte aussi stupide
que la suivante, est suppose fonctionner :
exemple 10
SELECT CLI_NOM
FROM T_CLIENT
WHERE 1=1
CLI_NOM
-------
DUPONT
MARTIN
BOUVIER
DUBOIS
DREYFUS
FAURE
LACOMBE
DUHAMEL
BOYER
MARTIN
Attention : la plupart des SGBDR ne comportent pas de colonne
de type boolen. Une requte comme la premire risque
d'chouer.
exemple 1.12
SELECT *
FROM
TJ_CHB_PLN_CLI
WHERE
CHB_PLN_CLI_OCCUPE
ERREUR !
bien que CHB_PLN_CLI_OCCUPE puisse tre
du boolen, la plupart des compilateur
SQL n'accepte pas ce test direct.
SELECT *
FROM
TJ_CHB_PLN_CLI
WHERE
CHB_PLN_CLI_OCCUPE =
True
CORRECT ...
Mais sur certains compilateur SQL il faut
faire : CHB_PLN_CLI_OCCUPE = 'True'
(littral). Si le type boolen n'existe
pas, alors il faut faire
CHB_PLN_CLI_OCCUPE = 1
si l'on a choisi de dfinir les boolens
comme INTEGER(1) avec 0 et 1
exemple 11

3.1) Oprateurs de comparaison

Dans la clause WHERE, vous disposez de diffrents oprateurs
de comparaisons logiques :

WHERE valeur1 [NOT et] = ou < ou <= ou > ou >= ou <>valeur2
[OR ou AND ...]

exemple 12
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
WHERE CLI_NOM >= 'A' AND CLI_NOM <'E'
ou
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
WHERE (CLI_NOM >= 'A')
AND
(CLI_NOM <'E')
plus lisible !
CLI_NOM CLI_PRENOM
------- ----------
DUPONT Alain
BOUVIER Alain
DUBOIS Paul
DREYFUS Jean
DUHAMEL Evelyne
BOYER Martine
DUVAL Arsne
DAUMIER Amlie
CHABAUD Daniel
BAILLY Jean-Franois
...

Ici on obtient tous les noms et prnoms des clients dont le
nom commence par les lettres A, B, C ou D.
Attention : dans certains moteurs de requte SQL loprateur
diffrend de (<>) scrit !=

3.2) Oprateur IN

L'oprateur IN permet de rechercher si une valeur se trouve
dans un ensemble donn, quel que soit le type des valeurs de
rfrence spcifies (alpha, numrique, date). Bien entendu,
il est possible dinverser le fonctionnement de loprateur IN
en lui adjoignant loprateur NOT.

exemple 13
SELECT TIT_CODE, CLI_NOM,
CLI_PRENOM
FROM T_CLIENT
WHERE TIT_CODE IN ('Mme.',
'Melle.')
TIT_CODE CLI_NOM
CLI_PRENOM
-------- ---------- -------
---
Mme. BOYER Martine
Mme. GALLACIER Nolle
Mme. HESS Lucette
Mme. LETERRIER Monique
Mme. MARTINET Carmen
Mme. DAVID
Jacqueline
Mme. MOURGUES
Jacqueline
Mme. ZAMPIERO Annick
Mme. ROURE Marie-
Louise
Mme. DE CONINCK
Patricia
...

On recherche les clients de sexe fminin, bass sur le code
titre
Le contenu de la parenthse peut tre remplac par le resultat
d'une requte possdant une colonne unique. Dans ce cas on
parle de requtes imbriques, ce que nous verrons plus loin.

3.3) Oprateur BETWEEN

L'oprateur BETWEEN permet de rechercher si une valeur se
trouve dans un intervalle donn, quel que soit le type des
valeurs de rfrence spcifies (alpha, numrique, date)
Ainsi, la requte vue dans l'exemple 12 peut s'crire :

Exemple 14
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
WHERE CLI_NOM BETWEEN 'A' AND 'E'
CLI_NOM CLI_PRENOM
------- ----------
DUPONT Alain
BOUVIER Alain
DUBOIS Paul
DREYFUS Jean
DUHAMEL Evelyne
BOYER Martine
DUVAL Arsne
DAUMIER Amlie
CHABAUD Daniel
BAILLY Jean-Franois
...

NOTA : les oprateurs IN et BETWEEN sont trs pratiques dans
le cas o lon dsire effectuer des requtes o lutilisateur
peut saisir une liste de choix multiples (IN) ou une plage de
valeur (BETWEEN).

3.4) Oprateurs LIKE

L'oprateur LIKE permet deffectuer une comparaison partielle.
Il est surtout employ avec les colonnes contenant des donnes
de type alpha. Il utilise les jokers % et _ (pour cent et
blanc soulign). Le joker % remplace n'importe quelle chane
de caractres, y compris la chane vide. Le blanc soulign
remplace un et un seul caractre.

exemple 15
SELECT CLI_NOM, CLI_PRENOM
FROM T_CLIENT
WHERE CLI_NOM LIKE B%
CLI_NOM CLI_PRENOM
------- ----------
BOUVIER Alain
BOYER Martine
BAILLY Jean-Franois
BOUCHET Michel
BEAUNEE Pierre
BERGER Jean-Pierre
BOURA Andr
BENZAQUI Jol
BAVEREL Frdric
BERTRAND Christophe
...

On recherche les client dont le nom commence par B.
Mais si vos donnes sont susceptibles de contenir un des deux
caractres joker, alors il faut recourir une squence
dchappement, laide du mot clef ESCAPE
Cherchons les clients dont l'enseigne contient au moins un
caractre blanc soulign :

exemple 16
SELECT *
FROM T_CLIENT
WHERE
CLI_ENSEIGNE
LIKE %_%
CLI_ID TIT_CODE CLI_NOM CLI_PRENOM CLI_ENSEIGNE
------ -------- ---------- ------------- ---------------
2 M. MARTIN Marc Transports
MARTIN & fils
6 M. FAURE Alain Boulangerie du
march
10 M. MARTIN Martin HERMAREX
IMPORT_EXPORT
11 M. PAUL Marcel Cie
Internationale des Machines Electrom...
17 M. BAILLY Jean-Franois Entreprise
DUPONT CHAUFFAGE
24 M. CHTCHEPINE Dominique HOTEL *** DE LA
GARE
26 M. GARREAU Paul IBM Corp.
34 Mme. GALLACIER Nolle Transports
GALLACIER
42 Mme. LETERRIER Monique SA AROMAX
ENTREVONT
49 M. COULOMB Renaud Cabinet COULOMN
et CALEMANT
...
SELECT *
FROM T_CLIENT
WHERE
CLI_ENSEIGNE
LIKE '%#_%'
ESCAPE '#'
CLI_ID TIT_CODE CLI_NOM CLI_PRENOM CLI_ENSEIGNE
------ -------- ---------- ------------- -------------
10 M. MARTIN Martin HERMAREX
IMPORT_EXPORT

Pour traiter ce cas, on dfini # comme caractre
dchappement. Le caractre qui suit ce caractre
dchappement est donc interprt comme un caractre et non
comme un joker.
NOTA : loprateur LIKE effectue une recherche en tenant
compte de la diffrence entre lettres majuscules et
minuscules. Si vous voulez effectuer une recherche en ne
tenant aucunement compte de la diffrence entre majuscules et
minuscules, il convient dutiliser les oprateurs LOWER et
UPPER (voir ci dessous). Mais la plupart du temps,
l'utilisation du like dans un SGBDR donn ignore la casse.

3.5) Rsum des oprateurs pour les prdicats de la clause
WHERE

Voici une tableau rsumant les principaux oprateurs utiliss
pour la construction des prdicats :

oprateurs de comparaisons = <> < <= > >=
connecteurs logiques {OR | AND}
oprateur de ngation NOT
parenthses ( ... )
oprateurs mathmatiques + - * /
comparaison logique IS [NOT] {TRUE | FALSE |
UNKNOWN}
comparaison avec valeur IS [NOT] NULL
intervalle valeur BETWEEN borne_basse AND
borne_haute
comparaison partielle de chane
de caractres
valeur LIKE motif [ESCAPE
echappement]
comparaison une liste de
valeur
valeur [NOT] IN (liste)

4) Fonctions diverses

4.1) Transtypage l'aide de la fonction CAST

Il permet de changer le type de donnes d'une colonne afin
deffectuer une comparaison de donnes de type htrogne par
exemple entre un champ contenant des donnes numriques et un
champ contenant des donnes de type chane de caractres
Sa syntaxe est CAST(colonne AS nouveau type).

Loprateur CAST permet de transtyper les valeurs contenues
dans une colonne. Bien entendu il faut qu'un type de donne
puisse tre convertis dans un autre type (compatibilit de
types) afin que le rponse ne soit pas entch d'erreurs ou
d'ommissions.

exemple 18
SELECT ADR_VILLE,
CAST(ADR_CP AS
INTEGER) + 1
FROM T_ADRESSE
ADR_VILLE ADR_CP ADR_CP + 1
------------ ------ ----------
VERSAILLES 78000 78001
MONTMAIZIN 11254 11255
PARIS 75015 75016
VERGNOLLES CEDEX 452 84524 84525
MARSEILLE 13002 13003
PARIS 75012 75013
BONNEUIL CEDEX 94152 94153
PARIS 75012 75013
PARIS 75014 75015
PARIS 75017 75018
...

4.2) Mise en majuscule / Minuscule

Les oprateurs LOWER et UPPER permettent de mettre en
majuscule ou en minuscule des chanes de caractres dans les
requtes.

exemple 19
SELECT upper(CLI_PRENOM), lower(CLI_NOM)
FROM T_CLIENT
CLI_NOM CLI_PRENOM
------- ----------
ALAIN dupont
MARC martin
ALAIN bouvier
PAUL dubois
JEAN dreyfus
ALAIN faure
PAUL lacombe
EVELYNE duhamel
MARTINE boyer
MARTIN martin
...
NOTA : pour effectuer une recherche en ne tenant aucunement
compte de la diffrence entre majuscules et minuscules, il
faut utiliser loprateur UPPER (ou lower mais attention la
transformation des accents !) :

4.3) Supprimer les blancs (ou tout autre caractres)

La fonction TRIM permet de supprimer en tte ou en queue (ou
les deux) le blanc ou tout autre caractre spcifi.

TRIM ([LEADING ou TRAILING ou BOTH] [caractre] FROM nom de
colonne)
LEADING : suppression en tte
TRAILING : suppression en queue
BOTH : suppression en tte et en queue

Dans notre table tlphone, nous voulons supprimer le zro de
tte des n afin de pouvoir les communiquer aux trangers qui
nont pas besoin de composer ce chiffre (ils doivent
simplement composer le 00 33 suivi du numro 9 chiffres).

exemple 21
SELECT TEL_NUMERO,
00~33 ||
TRIM(LEADING 0 FROM
TEL_NUMERO)
AS
TEL_INTERNATIONAL
FROM T_TELEPHONE
TEL_NUMERO TEL_INTERNATIONAL
-------------- -----------------
01-45-42-56-63 00~33 1-45-42-56-63
01-44-28-52-52 00~33 1-44-28-52-52
01-44-28-52-50 00~33 1-44-28-52-50
06-11-86-78-89 00~33 6-11-86-78-89
02-41-58-89-52 00~33 2-41-58-89-52
01-51-58-52-50 00~33 1-51-58-52-50
01-54-11-43-21 00~33 1-54-11-43-21
06-55-41-42-95 00~33 6-55-41-42-95
01-48-98-92-21 00~33 1-48-98-92-21
01-44-22-56-21 00~33 1-44-22-56-21
...
NOTA : certains serveurs SQL proposent diffrentes fonctions
comme LTRIM et RTRIM pour une suppression des blancs en tte
ou en queue.

4.4) Extraire une sous chane

La fonction SUBSTRING permet dextraire une sous chane dune
chane de caractre. Elle a besoin de lordre du premier
caractre et du nombre de caractres sur lequel elle doit
oprer.

SUBSTRING ( nom de colonne FROMnTOm)
Extrait la sous chane de nom de colonne en commenant n sur
m caractres.

exemple 22

SELECT CLI_NOM, CLI_PRENOM,
SUBSTRING(CLI_PRENOM
FROM 1 FOR 1) ||
SUBSTRING(CLI_NOM
FROM 1 FOR 1)
AS INITIALES
FROM T_CLIENT
CLI_NOM CLI_PRENOM INITIALES
------- ---------- ---------
DUPONT Alain AD
MARTIN Marc MM
BOUVIER Alain AB
DUBOIS Paul PD
DREYFUS Jean JD
FAURE Alain AF
LACOMBE Paul PL
DUHAMEL Evelyne ED
Cet exemple construit les initiales des clients partir des
colonnes CLI_NOM et CLI_PRENOM_CLI
Attention, certains SGBDR utilisent la fonction SUBSTR

4.5) Oprateur de traitement des dates

4.5.1) Extraire un paramtre temporel d'une date

Loprateur EXTRACT permet dextraire depuis une date, le jour
le mois ou lanne

EXTRACT ( YEAR ou MONTH ou DAY FROM nom de colonne )

Dans la table des rservation on recherche l'identifiant des
chambres ayant t rserves au cours du mois de mai de
n'importe quelle anne et pour 3 personnes

exemple 23


SELECT distinct CHB_ID
FROM TJ_CHB_PLN_CLI
WHERE EXTRACT(MONTH FROM PLN_JOUR) = 5
AND CHB_PLN_CLI_RESERVE = 1
AND CHB_PLN_CLI_NB_PERS = 3
CHB_ID
------
1
5
6
8
11
12
16
17
18
20
NOTA : il est dommage de constater que la fonction EXTRACT du
standard SQL, souvent fort utile, est rarement prsente dans
les moteurs de bases de donnes. Ni Access, ni Oracle, ni
Sybase, ni SQL Server en sont dot. Seul le middleware BDE de
Borland Inprise Corel permet d'exploiter pleinement cette
fonction avec les SGBDR Paradox, dBase, FoxPro, InterBase,
MSSQL, Sybase, Informix, DB2, Oracle.

4.5.2) Heure et date courante

Lheure courante, la date courante et le combin date/heure
courant peuvent tre obtenu laide des fonctions
CURRENT_DATE, CURRENT_TIME et CURRENT_TIMESTAMP
exemple 24


SELECT distinct CHB_ID
FROM TJ_CHB_PLN_CLI
WHERE (CHB_PLN_CLI_RESERVE = 1)
AND PLN_JOUR BETWEEN CURRENT_DATE and
CHB_ID
------
1
5
6
CURRENT_DATE + 14
AND CHB_PLN_CLI_NB_PERS = 3
attention, le rsultat de cette requte varie en
fonction de la date laquelle vous l'excutez !
8
11
12
16
17
18
20

Cette requte renvoi les chambres rserves pour 3 personnes
entre la date du jour et pour les deux semaines venir .
Attention : la plupart des SGBDR n'acceptent pas encore cette
version normalise des fonctions de recherche de temps
courant. Voici les fonctions spcifiques aux diffrents
serveurs SQL :

Oracle SYSDATE()
Sybase GETDATE()
SQLServer GETDATE()
Access NOW()
MySQL NOW()
Paradox (QBE) TODAY

4.6) Oprateurs statistiques

Il est possible de raliser des comptages statistiques sur les
colonnes, l'aide des oprateurs AVG (moyenne), MAX
(maximum), MIN (minimum), SUM (total), COUNT (nombre). On les
appellent aussi fonctions d'agrgations.

exemple 25

SELECT
AVG(TRF_CHB_PRIX)
as MOYENNE,
MAX(TRF_CHB_PRIX)
as MAXI,
MIN(TRF_CHB_PRIX)
as MINI,
SUM(TRF_CHB_PRIX)
as TOTAL,
COUNT(TRF_CHB_PRIX)
as NOMBRE
FROM TJ_TRF_CHB
WHERE
TRF_DATE_DEBUT =
2001-01-01
MOYENNE MAXI MINI TOTAL NOMBRE
-------- -------- -------- ---------- ------
406,74 F 512,00 F 352,00 F 7 728,00 F 19

Cette requte calcule la moyenne, le montant maximum, minimum,
la totalisation et le nombre des tarifs de chambre pour la
date de dbut du premier janvier 2001.

4.7) Autres fonctions normalises


BIT_LENGTH Taille d'une colonne de type BIT ou BIT
VARYING (nombre de bits)
CHAR_LENGTH Taille d'une colonne de type caractre
(nombre de caractres)
OCTET_LENGTH Taille d'une colonne de type caractre
(nombre d'octets)
CURRENT_DATE Date en cours
CURRENT_TIME Heure en cours
CURRENT_TIMESTAMP Date et heure en cours
CONVERT Conversion paramtre d'une chane de
caractres
POSITION Position d'une chane de caractres dans une
sous chane
TRANSLATE Traduction d'une chane de caractres dans un
format spcifi


4.8) Autres oprateurs mathmatiques (non normaliss)

Les oprateurs ci dessous peuvent tre implments dans
diffrents moteurs.

ABS valeur absolue
MOD modulo
SIGN signe
SQRT racine carre
CEIL plus petit entier
FLOOR plus grand entier
ROUND arrondi
TRUNC tronqu
EXP exponentielle
LN logarithme nprien
LOG logarithme dcimal
POWER puissance
COS cosinus
COSH cosinus hyperbolique
SIN sinus
SINH sinus hyperbolique
TAN tangente
TANH tangente hyperbolique
PI constante Pi

Certains sont rarement implments du fait que les SGBDR sont
axs sur linformatique de gestion, la collecte et le
traitement dinformations et non le calcul mathmatique.

6) Ngation de valeurs

C'est l'oprateur NOT qui ralise la ngation de valeurs et
inverse la valeur logique d'un prdicat.
L'oprateur NOT peut tre combin avec la plupart des
oprateurs de comparaison. Mais il devient trs intressant
lorsqu'il est combin aux oprateurs IN, BETWEEN, LIKE et NULL
Recherchons par exemples toutes les chambres permettant de
recevoir au moins 3 personnes, ne comportant pas le chiffre 4
(chiffre de la mort au japon) ni les chambres portant les n
7 et 13 pour un client particulirement superstitieux...

exemple 29

SELECT CHB_ID, CHB_NUMERO,
CHB_COUCHAGE
FROM T_CHAMBRE
WHERE NOT (CAST(CHB_NUMERO
AS VARCHAR(10)) LIKE '%4%')
AND CHB_NUMERO NOT
IN ('7', '13')
AND CHB_COUCHAGE >=
3
CHB_ID CHB_NUMERO CHB_COUCHAGE
----------- ---------- ------------

1 1 3
5 5 3
6 6 5
8 8 3
11 11 3
12 12 3
15 16 3
16 17 5
17 18 3
19 20 3

Nous verrons que le NOT IN est particulirement prcieux dans
les requtes imbriques, c'est dire les requtes multi-
tables. Nous voulons maintenant le nom des clients qui ne
commence pas par 'DU' :

exemple 1.30
SELECT CLI_NOM
FROM T_CLIENT
WHERE CLI_NOM NOT LIKE 'DU%'
CLI_NOM
--------------------------------
MARTIN
BOUVIER
DREYFUS
Remarque

En ce qui concerne MS Access, on ne peut qutre frapp par le
fait que la plupart des fonctions de base des requtes sont
incompatible avec la norme. Par exemple le LIKE utilise des
jokers diffrent : * remplace le % et ? remplace le _. Cela
oblige utiliser une syntaxe propritaire qui rend la
portabilit des requtes trs difficile dun SGBDR lautre.
Mais ne serait-ce pas l une tactique voulue ??? Autre
inconvnient il ne sait pas traiter le NOT BETWEEN !!!
Plus curieux la plupart des SGBDR n'accepte pas l'oprateur de
concatnation ||!

Le SGBDR le plus proche de la norme est celui de Sybase, suivi
de SQL Server. Le plus complet par son jeu de fonction est
sans doute Oracle.



































1Z C1 CW m m Z
@WUW @m2UW " UW CUI2W
1m2 12WCW2UC ZLmZL

Ug 1W wCUI2W C CCUUWI 2mU2W CW 2W@WW 2 @UUW2
mUW

Les jointures permettent d'exploiter pleinement le modle
relationnel des tables d'une base de donnes.
Elle sont faites pour mettre en relation deux (ou plus) tables
concourant rechercher la rponse des interrogations. Une
jointure permet donc de combiner les colonnes de plusieurs
tables.
Il existe en fait diffrentes natures de jointures que nous
expliciterons plus en dtail. Retenez cependant que la plupart
des jointures entre tables s'effectuent en imposant l'galit
des valeurs d'une colonne d'une table une colonne d'une
autre table. On parle alors de jointure naturelle ou qui-
jointure. Mais on trouve aussi des jointures d'une table sur
elle mme. On parle alors d'auto-jointure. Enfin il arrive que
l'on doive procder des jointures externe, c'est dire
joindre une table une autre, mme si la valeur de liaison
est absente dans une table ou l'autre. Enfin, dans quelques
cas, on peut procder des jointures htrognes, c'est
dire que l'on remplace le critre d'galit par un critre
d'ingalit ou de diffrence. Nous verrons au moins un cas de
cet espce.
Une jointure entre tables peut tre mise en oeuvre, soit
l'aide des lments de syntaxe SQL que nous avons dj vu,
soit l'aide d'une clause spcifique du SQL, la clause wLUW.
Nous allons commencer par voir comment l'aide du SQL de base
nous pouvons exprimer une jointure.
UU 12WUUW2 WmU CW CUI2W
Rappel de la syntaxe du SELECT :
CZ1ZL [LUCUWL ou m11] ou liste de colonnes 1ZLD nom des
tables ou des vues
C'est ici le pluriel du la partie FROM qui change tout...
Tchons donc de rcuprer les n des tlphones associs aux
clients
exemple 1
SELECT CLI_NOM, TEL_NUMERO
FROM T_CLIENT, T_TELEPHONE
CLI_NOM TEL_NUMERO
------- --------------
DUPONT 01-45-42-56-63
DUPONT 01-44-28-52-52
DUPONT 01-44-28-52-50
DUPONT 06-11-86-78-89
DUPONT 02-41-58-89-52
DUPONT 01-51-58-52-50
DUPONT 01-54-11-43-21
DUPONT 06-55-41-42-95
DUPONT 01-48-98-92-21
DUPONT 01-44-22-56-21
...
Cette requte ne possde pas de critre de jointure entre une
table et l'autre. Dans ce cas, le compilateur SQL calcule le
produit cartsien des deux ensembles, c'est dire qu' chaque
ligne de la premire table, il accole l'ensemble des lignes de
la seconde la manire d'une "multiplication des petits
pains" ! Nous verrons qu'il existe une autre manire,
normalise cette fois, de gnrer ce produit cartsien. Mais
cette requte est proscrire. Dans notre exemple elle gnre
17 400 lignes...
,OIDXWGRQFGpILQLUDEVROXPHQWXQFULWqUHGHMRLQWXUH
Dans le cas prsent, ce critre est la correspondance entre
les colonnes contenant la rfrence de l'identifiant du client
(CLI_ID).
exemple 2
SELECT CLI_NOM, TEL_NUMERO
FROM T_CLIENT, T_TELEPHONE
WHERE CLI_ID = CLI_ID
CLI_NOM TEL_NUMERO
------- --------------
DUPONT 01-45-42-56-63
DUPONT 01-44-28-52-52
DUPONT 01-44-28-52-50
DUPONT 06-11-86-78-89
DUPONT 02-41-58-89-52
DUPONT 01-51-58-52-50
DUPONT 01-54-11-43-21
DUPONT 06-55-41-42-95
Nous n'avons pas fait mieux, car nous avons cr une clause
toujours vrai, un peu la manire de 1 = 1 ! En fait il nous
manque une prcision : il s'agit de dtermin de quelles table
proviennent les colonnes CLI_ID de droite et de gauche. Cela
ce prcise l'aide d'une notation pointe en donnant le nom
de la table.
Il est donc ncessaire d'indiquer au compilateur la provenance
de chacune des colonnes CLI_ID et donc d'oprer une
distinction entre l'une et l'autre colonne. Ainsi, chaque
colonne devra tre prcde du nom de la table, suivi d'un
point.
exemple 3
SELECT CLI_NOM, TEL_NUMERO
FROM T_CLIENT, T_TELEPHONE
WHERE T_CLIENT.CLI_ID = T_TELEPHONE.CLI_ID
CLI_NOM TEL_NUMERO
------- --------------
DUPONT 01-45-42-56-63
DUPONT 01-44-28-52-52
DUPONT 01-44-28-52-50
BOUVIER 06-11-86-78-89
DUBOIS 02-41-58-89-52
DREYFUS 01-51-58-52-50
DUHAMEL 01-54-11-43-21
BOYER 06-55-41-42-95
MARTIN 01-48-98-92-21
MARTIN 01-44-22-56-21
...
On tombe ici 174 enregistrements dans la table !!!
Mais il existe une autre faons de faire, plus simple encore.
On utilise la technique du "2ICUUmW", c'est dire que l'on
attribut un surnom chacune des tables prsente dans la
partie FROM du SELECT :
exemple 4
SELECT CLI_NOM, TEL_NUMERO
FROM T_CLIENT C, T_TELEPHONE T
WHERE C.CLI_ID = T.CLI_ID
CLI_NOM TEL_NUMERO
------- --------------
DUPONT 01-45-42-56-63
DUPONT 01-44-28-52-52
DUPONT 01-44-28-52-50
BOUVIER 06-11-86-78-89
DUBOIS 02-41-58-89-52
DREYFUS 01-51-58-52-50
DUHAMEL 01-54-11-43-21
BOYER 06-55-41-42-95
MARTIN 01-48-98-92-21
MARTIN 01-44-22-56-21
...
Ici, la table T_CLIENT a t surnomme "C" et la table
T_TELEPHONE "T".
Bien entendu, et comme dans les requtes monotabulaires ont
peut poser des conditions supplmentaires de filtrage dans la
clause where. Cherchons par exemple les clients dont les
numros de tlphone correspondent un fax :
exemple 5
SELECT CLI_NOM, TEL_NUMERO
FROM T_CLIENT C, T_TELEPHONE T
WHERE C.CLI_ID = T.CLI_ID
AND TYP_CODE = 'FAX'
CLI_NOM TEL_NUMERO
------- --------------
DUPONT 01-44-28-52-50
MARTIN 01-44-22-56-21
DUHAMEL 01-54-11-43-89
DUPONT 05-59-45-72-42
MARTIN 01-47-66-29-55
DUBOIS 04-66-62-95-64
DREYFUS 04-92-19-18-58
DUHAMEL 01-55-60-93-81
PHILIPPE 01-48-44-86-19
DAUMIER 01-48-28-17-95
...
Le fait de placer comme critre de jointure entre les tables,
l'oprateur logique "gal" donne ce que l'on apelle une "W@U"
CUI2W".
WLm : on peut aussi utiliser les surnoms dans la partie qui
suit immdiatement le mot clef SELECT. Ainsi l'exemple 4, peut
aussi c'crire :
exemple 6
SELECT C.CLI_ID, C.CLI_NOM, T.TEL_NUMERO
FROM T_CLIENT C, T_TELEPHONE T
WHERE C.CLI_ID = T.CLI_ID
AND T.TYP_CODE = FAX
CLI_ID CLI_NOM TEL_NUMERO
------ ------- --------------
1 DUPONT 01-44-28-52-50
10 MARTIN 01-44-22-56-21
8 DUHAMEL 01-54-11-43-89
1 DUPONT 05-59-45-72-42
2 MARTIN 01-47-66-29-55
4 DUBOIS 04-66-62-95-64
5 DREYFUS 04-92-19-18-58
8 DUHAMEL 01-55-60-93-81
13 PHILIPPE 01-48-44-86-19
15 DAUMIER 01-48-28-17-95
...
C'est particulirement pratique lorsque l'on veut rcuprer
une colonne qui se retrouve dans les deux tables, ce qui est
souvent le cas de la (ou les) colonne de clef trangre qui
permet justement d'assurer la jointure.
Pour joindre plusieurs tables, on peut utiliser le mme
processus de manire rptitive...
exemple 7
SELECT C.CLI_ID, C.CLI_NOM, T.TEL_NUMERO, E.EML_ADRESSE,
A.ADR_VILLE
FROM T_CLIENT C, T_TELEPHONE T, T_ADRESSE A, T_EMAIL E
WHERE C.CLI_ID = T.CLI_ID
AND C.CLI_ID = A.CLI_ID
AND C.CLI_ID = E.CLI_ID
CLI_ID CLI_NOM TEL_NUMERO EML_ADRESSE ADR_VILLE
------ -------- -------------- -------------------- ---------
1 DUPONT 01-45-42-56-63 alain.dupont@wanadoo.fr VERSAILLES
1 DUPONT 05-59-45-72-42 alain.dupont@wanadoo.fr VERSAILLES
1 DUPONT 05-59-45-72-24 alain.dupont@wanadoo.fr VERSAILLES
1 DUPONT 01-44-28-52-50 alain.dupont@wanadoo.fr VERSAILLES
1 DUPONT 01-44-28-52-52 alain.dupont@wanadoo.fr VERSAILLES
2 MARTIN 01-47-66-29-55 plongeur@aol.com VERGNOLLES
5 DREYFUS 04-92-19-18-58 pdreyfus@club-internet.fr PARIS
DmUC mZWULW De mme que nous l'avons vu dans l'exemple
2.4, ne sont visible ici que les lignes clients ayant A LA
FOIS, au moins une adresse, un e mail et au moins un numro de
tlphone... Si nous avions voulu une liste complte des
clients avec toutes les coordonnes disponibles, nous aurions
du faire une requte externe sur les tables...
U LU22W2WI @W CW CUI2W _Im2WUUW_ W@U_ ICI
W@U_ mC_ W2W2IW_ WW2CWIW_ C2CUWW W IUCIg
Lorsque nous tudions le modle relationnel de notre base de
donnes exemple nous avons vu que le modle physique des
donnes, rpercute les clefs des tables matres en tant que
clefs trangres des tables pour lesquelles une jointure est
ncessaire. En utilisant la jointure entre clefs primaires et
clefs secondaires base sur l'galit des valeurs des colonnes
nous excutons ce que les professionnels du SQL appelle une
CUI2W Im2WUUW. Il est aussi possible de faire des W@U"
CUI2W qui ne sont pas naturelles, soit par accident (une
erreur !), soit par ncessit. Il est aussi possible de faire
des ICI W@U"CUI2W, c'est dire des jointures base sur
un critre diffrent de l'galit, mais aussi des mC"
CUI2W, c'est dire de joindre la table sur elle mme. Le
cas le plus dlicat comprendre est celui des CUI2W
W2W2IW, c'est dire exiger que le rsultat comprenne toutes
les lignes des tables (ou d'au moins une des tables de la
jointure), mme s'il n'y a pas correspondance des lignes entre
les diffrentes tables mise en oeuvre dans la jointure. La
CUI2W CIUCI consiste ajouter toutes les donnes des
deux tables condition qu'elles soient compatibles dans leurs
structures. La CUI2W C2CUWW permet de faire le produit
cartsien des tables. Enfin on peut effectuer des 2W@WW
WW2CWIW, c'est dire de joindre une table d'une base de
donnes, une ou plusieurs autres base de donnes
ventuellement mme sur des serveurs diffrents, voire mme
sur des serveurs de diffrents types (par exemple joindre une
table T_CLIENT de la base BD_COMMANDE d'un serveur Oracle la
table T_PROSPECT de la base BD_COMMERCIAL d'un serveur Sybase
!).


W LLWCZU1 UD1LZmW
Dans la mesure du possible, UUUW CC2 I C@W2mW2 CW
CUI2W IC2UmUUW _UC CUW2 wLUWg.
En effet :
les jointures faites dans la clause WHERE (ancienne
syntaxe de 1986 !) ne permettent pas de faire la
distinction de prime abord entre ce qui relve du
filtrage et ce qui relve de la jointure.
Il est priori absurde de vouloir filtrer dans le WHERE
(ce qui restreint les donnes du rsultat) et de voiloir
"largir" ce rsultat par une jointure dans la mme
clause WHERE de filtrage.
La lisibilit des requtes est plus grande en utilisant
la syntaxe base de JOIN, en isolant ce qui est du
filtrage et de la jointure, mais aussi en isolant avec
clart chaque condition de jointures entre chaque couples
de table
L'optimisation d'excution de la requte est souvent plus
pointue du fait de l'utilisation du JOIN.
Lorsque l'on utilise l'ancienne syntaxe et que l'on
supprime la clause WHERE a des fins de tests, le moteur
SQL ralise le produit cartsiens des tables ce qui
revient la plupart du temps mettre genoux le serveur
!

CIm2W IC2UmUUWW CW CUI2W
Les jointures normalises s'expriment l'aide du mot clef
wLUW dans la clause FROM. Suivant la nature de la jointure, on
devra prciser sur quels critres se base la jointure.
Voici un tableau rsumant les diffrents types de jointures
normalises :

Jointure interne SELECT ...
FROM <table gauche>
[UWWZZ]wLUW <table droite>
LW <condition de jointure>
Jointure externe SELECT ...
FROM <table gauche>
1Z1 | ZUL | 111 LZZ wLUW <table
droite>
LW condition de jointure
Jointure
naturelle
SELECT ...
FROM <table gauche>
WmZm1wLUW <table droite>
[CUWL <noms de colonnes>]
Jointure croise SELECT ...
FROM <table gauche>
LZLCCwLUW <table droite>
Jointure d'union SELECT ...
FROM <table gauche>
WULWwLUW <table droite>
ZWCm@UUmU2 CW CUI2W IC2UmUUWW
U W2UUICUCUW W Im2W CW CUI2W
wLUWZZ WmZZ11Z : la jointure seffectue sur les colonnes
communes, c'est dire celles de mme nom et type :
CZ1ZL colonnes 1ZLD table1 WmZm1wLUW table2 [CUWL col1,
col2 ... ] [WZZZ prdicat] ...
Le mot clef USING permet de restreindre les colonnes communes
prendre en considration
wLUWZZ UWZZWZ : la jointure s'effectue entre les tables sur
les colonnes prcises dans la condition de jointure :
CZ1ZL colonnes 1ZLD table1 t1 [UWWZZ ] wLUW table2 t2 LW
FRQGLWLRQ[WZZZ prdicat] ...
wLUWZZ ZZZZWZ : la jointure permet de rcuprer les lignes
des tables correspondant au critre de jointure, mais aussi
celle pour lesquelles il n'existe pas de correspondances.
CZ1ZL colonnes 1ZLD table1 t1 [ZUL LZZ | 1Z1 LZZ |
111 LZZ ] wLUW table2 t2 LW FRQGLWLRQ [WZZZ prdicat] ...
RIGHT OUTER : la table droite de l'expression clef "RIGHT
OUTER" renvoie des lignes sans correspondance avec la table
gauche.
LEFT OUTER : la table gauche de l'expression clef "LEFT
OUTER" renvoie des lignes sans correspondance avec la table
droite.
FULL OUTER : les deux tables renvoient des lignes sans
correspondance entre elles.
wLUWZZ LZLUCZZ : la jointure effectue le produit cartsien
(la "multiplication") des deux tables. Il n'y a pas de
condition
CZ1ZL colonnes 1ZLD table1 t1 LZLCC wLUW table2 t2 [WZZZ
prdicat] ...
wLUWZZ LWULW : la jointure concatne les tables sans
aucune correspondances de colonnes
CZ1ZL colonnes 1ZLD table1 UNION wLUW table2
Il n'y a pas de critre de jointure



1Z C1 CW m m Z
WUW @m2UW " 2C@mW_ C WIWUUW W C@W2mW2
WIWUUUW
1m2 12WCW2UC ZLmZL

U 1m CUmW LZL1
La clause BROUP BY est ncessaire ds que l'on utilise des
fonctions de calculs statistiques avec des donnes bruts.
Cette clause groupe les lignes slectionnes en se basant sur
la valeur de colonnes spcifies pour chaque ligne et renvoie
une seule ligne par groupe.
On peut la comparer une opration de dcoupage de sous
ensemble un peut la manire des "niveaux de rupture" lorsque
l'on ralise des tats imprims.
Cherchons compter le nombre de chambre par tage de notre
htel :
exemple 1
SELECT COUNT(CHB_ID) AS NOMBRE, CHB_ETAGE
FROM T_CHAMBRE
La requte, telle que prsente ci dessus n'est pas
calculable. En effet comment dcider si le comptage doit se
faire pour chaque chambre ou pour un groupe de chambre et
notamment les groupes forms par chacun des tages ?
Si la requte se faisait pour chaque chambre, le rsultat
serait :
NOMBRE CHB_ETAGE
----------- ---------
1 RDC
1 RDC
1 RDC
1 RDC
1 1er
1 1er
1 1er
1 1er
1 1er
...
Et n'aurait pas beaucoup de sens !
En revanche, un regroupement par tage, donne tout son sens
la requte :
NOMBRE CHB_ETAGE
----------- ---------
8 1er
8 2e
4 RDC
Pour raliser un tel regroupement il faut introduire une
clause de groupage dans la requte. Pour cela SQL fournit le
clause GROUP BY :
exemple 1 (bis)
SELECT COUNT(*) AS NOMBRE, CHB_ETAGE
FROM T_CHAMBRE
GROUP BY CHB_ETAGE
WLm
La prsence de la clause GROUP BY est ncessaire ds que
la clause de slection, ou le filtre WHERE, ou encore les
jointures comportent simultanment des calculs
d'agrgation et la prsence de colonnes de table hors de
calculs d'agrgation.
De plus, toutes les colonnes reprsentes hors des
calculs d'agrgation doivent figurer dans la clause GROUP
BY
La plupart du temps, le moteur de requte vous avertira d'un
probable incohrence de calcul des agrgats l'aide d'un
message d'erreur (avant excution de la requte), du genre :
"/D FRORQQH HVW LQFRUUHFWH GDQV OD OLVWH GH VpOHFWLRQ
SDUFH TXHOOH QHVW SDV FRQWHQXH GDQV XQH IRQFWLRQ
GDJUpJDWLRQHWTXLOQ\DSDVGHFODXVH*5283%<"
Cherchons maintenant compter le couchage de chaque tage :
exemple 2
SELECT SUM(CHB_COUCHAGE) AS NOMBRE, CHB_ETAGE
FROM T_CHAMBRE
GROUP BY CHB_ETAGE
NOMBRE CHB_ETAGE
----------- ---------
23 1er
22 2e
9 RDC
Un peu plus compliqu, cherchons savoir quel a t le nombre
de nuites pour chaque chambre au cours de l'anne 1999 (une
nuite tant une personne passant une nuit dans une chambre.
Si deux personnes occupent la mme chambre cela fait deux
nuites) :
exemple 3
SELECT SUM(CHB_PLN_CLI_NB_PERS), C.CHB_ID
FROM T_CHAMBRE C
JOIN TJ_CHB_PLN_CLI P
ON C.CHB_ID = P.CHB_ID
WHERE PLN_JOUR BETWEEN '1999-01-01' AND '1999-12-31'
GROUP BY C.CHB_ID
PERSONNE CHB_ID
----------- -----------
558 1
385 2
322 3
367 4
445 5
720 6
390 7
456 8
362 9
364 10
529 11
468 12
347 13
360 14
484 15
720 16
491 17
372 18
504 19
369 20
Partant de la, nous pouvons rechercher le taux d'occupation de
chaque chambre dans cette priode. Le nombre maximal de
nuites tant le nombre de couchage de chaque chambre
multipli par toutes les dates de l'anne, ce calcul s'obtient
par :

exemple 4
SELECT SUM(CHB_COUCHAGE) AS MAX_OCCUPATION, CHB_ID
FROM T_CHAMBRE C
CROSS JOIN T_PLANNING P
WHERE PLN_JOUR BETWEEN 1999-01-01 AND 1999-12-31
GROUP BY C.CHB_ID
MAX_OCCUPATION CHB_ID
-------------- -----------
1095 1
730 2
730 3
730 4
1095 5
1825 6
730 7
1095 8
730 9
730 10
1095 11
1095 12
730 13
730 14
1095 15
1825 16
1095 17
730 18
1095 19
730 20
Il ne suffit plus que de "raccorder" les requtes des exemples
3 et 4 :
exemple 5
SELECT (CAST(SUM(CHB_PLN_CLI_NB_PERS) AS FLOAT) /
CAST(SUM(CHB_COUCHAGE) AS FLOAT)) * 100 AS
TAUX_OCCUPATION_POURCENT,
C.CHB_ID
FROM T_CHAMBRE C
JOIN TJ_CHB_PLN_CLI CPC
ON C.CHB_ID = CPC.CHB_ID
CROSS JOIN T_PLANNING P
WHERE P.PLN_JOUR BETWEEN '1999-01-01' AND '1999-12-31'
GROUP BY C.CHB_ID
TAUX_OCCUPATION_POURCENT CHB_ID
-------------------------- -----------
65.293040293040292 1
74.606580829756794 2
74.64488636363636 3
74.660326086956516 4
65.301318267419958 5
60.27972027972028 6
74.759284731774414 7
67.191977077363902 8
75.878378378378372 9
75.681198910081747 10
67.715458276333777 11
65.209471766848822 12
75.920873124147334 13
74.595687331536382 14
67.343256653134858 15
61.162162162162161 16
66.891284815813108 17
77.762982689747005 18
65.900900900900908 19
76.625172890733069 20
Nous allons voir, maintenant que la clause GROUP BY est
souvent utilise avec la clause HAVING...
1m CUmW mMUWL
La clause HAVING agit comme le filtre WHERE, mais permet de
filtrer non plus les donnes, mais les oprations rsultant
des regroupements, c'est dire trs gnralement toute
expression de filtre devant introduire un calcul d'agrgation.
Pour tenter de comprendre l'utilit de la clause having, nous
allons procder par un exemple simple : recherchons un tage
de l'htel capable de coucher au moins 20 personnes.
Partant de notre exemple 2, nous serions tenter d'crire :
exemple 6
SELECT SUM(CHB_COUCHAGE) AS NOMBRE, CHB_ETAGE
FROM T_CHAMBRE
WHERE SUM(CHB_COUCHAGE) >= 20
GROUP BY CHB_ETAGE
Mais cette requte va immanquablement provoquer une erreur
avant excution du fait de la clause WHERE. En effet,
souvenons nous que UW 2UU2W WZZZ mU 2 UW CCIIWW CW
mUW et permet de filtrer ligne aprs ligne. Or le filtrage
ne porte plus sur la notion de lignes, mais sur une notion de
sous ensemble de la table. En d'autre termes, le filtre, ici,
doit porter sur chacun des groupes. C'est pourquoi SQL
introduit le filtre mMUWL qui porte, non pas sur les donnes,
mais sur les calculs rsultants des regroupements.
En l'occurrence, dans notre exemple, nous devons dporter le
filtre WHERE dans la clause HAVING et l'opration deviendra
possible :
exemple 6 bis
SELECT SUM(CHB_COUCHAGE) AS NOMBRE, CHB_ETAGE
FROM T_CHAMBRE
GROUP BY CHB_ETAGE
HAVING SUM(CHB_COUCHAGE) >= 20
NOMBRE CHB_ETAGE
----------- ---------
23 1er
22 2e
@ 1W C@W2mW2 WIWUUUW
Cest une des parties les plus simple de lordre SELECT. A la
fois par sa syntaxe mais aussi par sa comprhension facile. Il
s'agit, ni plus ni moins que de raliser des oprations sur
les ensembles reprsents par des tables ou des extraits de
table. Les oprations ensemblistes du SQL sont l'union,
l'intersection et le diffrence.
@U 1WULW
Pour faire une union, il suffit de disposer de deux ensembles
de donnes compatibles et d'utiliser le mot clef UNION. La
syntaxe est alors :
SELECT ...
WULW
SELECT ...
Bien entendu il est indispensable que les deux ordres SELECT :
produisent un mme nombre de colonnes;
que les types de donnes de chaque paires ordonnes de
colonnes soient de mme type (ou d'un type quivalent).

@ 1UWZZCZLULW
La dmarche est la mme pour faire une intersection, que pour
le mcanisme de l'union. La syntaxe utilisant le mot clef
INTERSECT :
SELECT ...
UWZZCZL
SELECT ...
Avec les mmes contraintes d'ordre syntaxique
@@ 1m LU11ZZZWLZ
La diffrence de deux ensembles s'obtient de la mme manire,
en utilisant le mot clef EXCEPT :
SELECT ...
ZZLZ1
SELECT ...

@ m2W WC2U2W
L'intersection peut tre tablie par :
SELECT t1.col1, t1.col2 FROM t1
UWZZCZL
SELECT t2.col1, t2.col2 FROM t2
SELECT DISTINCT t1.col1, t1.col2
FROM t1
INNER JOIN t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2
SELECT DISTINCT t1.col1, t1.col2
FROM t1
WHERE EXISTS (SELECT *
FROM t2
WHERE t1.col1 = t2.col1 AND t1.col2 = t2.col2)
La diffrence peut tre tablie par :
SELECT t1.col1, t1.col2 FROM t1
ZZLZ1
SELECT t2.col1, t2.col2 FROM t2
SELECT DISTINCT t1.col1, t1.col2
FROM t1
WHERE NOT EXISTS (SELECT *
FROM t2
WHERE t1.col1 = t2.col1 AND t1.col2 =
t2.col2)
SELECT DISTINCT t1.col1, t1.col2
FROM t1
LEFT OUTER JOIN t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2
GROUP BY t1.col1, t1.col2
HAVING COUNT(t2.*) = 0
-- t2.* tant n'importe quelle colonne de t2



1Z C1 CW m m Z
TWUW @m2UW " UW UUW m C2 CW CCIIWW UWCZZ_ 1LmZ_
LZ1ZZ
1m2 12WCW2UC ZLmZL

Il existe une diffrence fondamentale entre l'ordre de
manipulation des donnes qu'est le SELECT et les diffrents
ordres de mise jour de donnes :
parce qu'en dehors de problmes de syntaxe ou de typage,
le select est une opration dont l'aboutissement est en
thorie toujours garantie (sauf indiquer des noms
d'objets inexistants) alors que les oprations de mise
jour des donnes sont susceptibles d'tre rejetes,
notamment si elle violent des contraintes,
parce qu'autant il est possible d'effectuer des
extractions de donnes via un ordre SELECT sur plusieurs
tables, autant il est impossible d'insrer, de modifier
ou de supprimer dans plusieurs tables simultanment.
parce qu'une requte de mise jour (INSERT, UPDATE ou
SELECT) est une transaction en elle mme et que tout doit
tre ralis, sinon rien ne se passe (en particulier si
une seule donne viole une contrainte aucune insertion,
mise jour ou suppression n'est effective dans le cas
d'un ordre concernant la mise jour de plusieurs lignes
simultanment).
parce qu' moins de grer une transaction et notamment
l'aide du mot clef ROLLBACK, il est impossible de revenir
sur un ordre de mise jour si l'on s'est tromp. Dans le
cas d'un SELECT ceci n'a pas d'importance puisque les
donnes ne sont pas modifies.
U UIW2W2 m UmUCW CUWCZZ

La syntaxe de base de l'ordre SQL d'insertion de donnes dans
une table est la suivante :

UWCZZ [UWL] nom_de_la_table_cible
[_liste_des_colonnes_visesg]
{Mm1ZC _liste_des_valeursg | requte_select | LZ1m1 Mm1ZC
}
WLm
la liste des colonnes vises peut tre omise condition
que l'ordre d'insertion concerne toutes les colonnes de
la table.
la liste des valeurs peut tre remplace par un
constructeur de lignes values pour une insertion de
plusieurs lignes en un seul ordre, mais rare sont les
SGBDR l'accepter (Oracle est l'un des rares SGBDR
accepter cette syntaxe).

mZWULW : l'ordre des valeurs de la liste doit tre le mme
que l'ordre des colonnes vises et cela, mme si la liste des
colonnes vises est omise.
ZZDmZZ :
Du fait de sa syntaxe, l'ordre INSERT se dcompose en trois
ordres assez diffrents :
Insertion simple explicite;
Insertion multiple explicite ( l'aide du constructeur de
lignes values;
Insertion base de sous requte SELECT;
Insertion des valeurs par defaut
Nous allons maintenant dtailler ces diffrentes dclinaisons
de l'ordre INSERT...
UU UIW2UCI UU@UW W2@UUCUW
Cette syntaxe porte sur l'insertion d'une ligne unique au sein
de la table. Il s'agit de prciser les valeurs insrer
explicitement.
exemple 1
INSERT INTO T_MODE_PAIEMENT (PMT_CODE, PMT_LIBELLE)
VALUES ('CB' , 'Carte bancaire')
Cet exemple propose d'insrer dans la table T_MODE_PAIEMENT
une ligne comportant les valeurs "CB" et "Carte bancaire" dans
les colonnes respectives PMT_CODE et PMT_LIBELLE.
WLm : lorsqu'une valeur n'est pas connue, il est possible de
prciser le mot clef NULL (marqueur) qui laisse la colonne
vide.
U UIW2UCI UUU@UW W2@UUCUW m UmUCW C CCI2CW2 CW
UUIW MmUWW
Cette syntaxe porte sur l'insertion de multiples ligne au sein
de la table cible. Il faut prciser les lignes de valeurs
insrer explicitement.
exemple 4
INSERT T_TITRE (TIT_CODE, TIT_LIBELLE)
VALUES (M. , Monsieur,
Mlle. , Mademoiselle
Mme. , Madame)
Cet exemple propose d'insrer dans la table T_TITRE trois
lignes de valeurs dans les colonnes TIT_CODE et TIT_LIBELLE.
U@ UIW2UCI @m2UWUUWUWI W2@UUCUW mMWC UW UC CUW2 LZ1m1
Si la dfinition de la table possde une ou plusieurs valeurs
par dfaut, alors il est possible de les y insrer en
utilisant le mot clef DEFAUT en lieu et place de la valeur.
Supposons que nous crons une table permettant de "pister" les
connexions la base de donnes, de la manire suivante :
CREATE TABLE T_SUIVI_CONNEXION
(CNX_USER VARCHAR(128) NOT NULL DEFAULT
'Administrateur',
CNX_DATE_HEURE TIMESTAMP NOT NULL DEFAULT
CURRENT_TIMESTAMP)
Alors nous pouvons insrer l'heure et la date par dfaut sans
en prciser la valeur, l'aide de la requte :
exemple 6
INSERT INTO T_SUIVI_CONNEXION (CNX_USER, CNX_DATE_HEURE)
VALUES ('Dupont', DEFAULT)
Qui insre automatiquement la valeur par dfaut dans la
colonne CNX_DATE_HEURE.
U UIW2UCI CmUWUWI UU@UUCUW mMWC UW2@2WUCI LZ1m1
Mm1ZC
Si chacune des colonnes de la dfinition de la table possde
des valeurs par dfaut, on peut demander l'insertion de toutes
les valeurs par dfaut en utilisant l'expression clef DEFAULT
VALUES. Dans ce cas il ne faut pas prciser les noms des
colonnes :
exemple 9
INSERT INTO T_SUIVI_CONNEXION
DEFAULT VALUES
Qui insrera l'utilisateur 'Administrateur' avec la date et
l'heure courante.
C@@2WUCI m UmUCW CW LZ1ZZ
La syntaxe de base de l'ordre SQL de suppression de donnes
dans une table est la suivante :
LZ1ZZ [1ZLD] nom_table_cible
[WZZZ condition]
Le seul cas pour lequel cet ordre peut ne pas aboutir est
lorsque la suppression viole la contrainte d'intgrit
rfrentielle. Il est en effet absurde de vouloir supprimer un
client si les factures relatives ce client n'ont pas t
pralablement supprimes.
WLm : Dans certains cas, il se peut que la suppression d'une
ligne entrane la suppressions d'autres lignes dans d'autres
tables lorsque existe des intgrits rfrentielles de
suppression en cascade.
U @@2WUCI CW CW UW UUIW CIW mUW
C'est la forme la plus simple de l'ordre DELETE puisqu'il
suffit d'omettre la clause WHERE :
exemple 15
DELETE FROM T_PROSPECT
Supprime tous les prospects.
@@2WUCI CCICUUCIIWUUW
Il suffit de rajouter la clause WHERE dote d'un prdicat
exemple 16
DELETE FROM T_PROSPECT
WHERE PRP_PRENOM LIKE '%d'
Supprime tous les prospects dont le nom se termine par la
lettre 'd'.
@ DCCU2UCmUCI m UmUCW C1LmZ
La syntaxe de base de l'ordre SQL de modification de donnes
dans une table est la suivante :
1LmZ nom_table_cible
CZ colonne valeur [, colonne2 = valeur2 ...]
[WZZZ condition]
@U DUW m C2 CIW CCUCIIW IU@W mI CCICUUCI
Cest la forme la plus simple de lordre UPDATE. Nous voulons
par exemple fixer 55 F les tarifs de nos petits djeuners
dans la table T_TARIF :
exemple 19
UPDATE T_TARIF
SET TRF_PETIT_DEJEUNE = 55
@ DUW m C2 CIW CCUCIIW IU@W mMWC 2W@2UW CW MmUW2
_mC 2W2W2WICWg
On peut aussi reprendre la valeur de la colonne (ou d'une
autre colonne de la table cible). Par exemple nous pouvons
demander une augmentation de 15% des tarifs des petits
djeuners :
exemple 20
UPDATE T_TARIF
SET TRF_PETIT_DEJEUNE = TRF_PETIT_DEJEUNE * 1.15
@@ DUW m C2 CIW CCUCIIW IU@W mMWC 2UU2mW
On peut ajouter une clause de filtrage WHERE dans une requte
de mise jour. Par exemple nous pouvons dcider de
n'augmenter de 15% que les tarifs des petits djeuners des
priodes postrieures 1999
exemple 21
UPDATE T_TARIF
SET TRF_PETIT_DEJEUNE = TRF_PETIT_DEJEUNE * 1.15
WHERE EXTRACT(YEAR FROM TRF_DATE_DEBUT) > 1999
@ DUW m C2 CW @UUW2 CCUCIIW UUUmIWUWI
Pour mettre jour simultanment plusieurs colonnes, il suffit
de rpter autant de fois que ncessaire le contenu de la
clause SET, raison d'un couple colonne/valeur par colonne
vises par la mise jour.
exemple 22
UPDATE T_CLIENT
SET CLI_NOM = UPPER(CLI_NOM),
CLI_PRENOM = UPPER(CLI_PRENOM)
CLI_ENSEIGNE = UPPER(CLI_ENSEIGNE)
WLm : dans ce cas, la nullit de l'excution de modification
d'une valeur dans une colonne possdant le marqueur NULL,
n'entrane pas la nullit de l'excution des mises jour des
autres colonnes, chaque modification de colonne tant values
sparment.

@C DUW m C2 mMWC C 2W@WW
Comme dans les ordres INSERT et DELETE, il est possible
d'utiliser une sous requte dans la clause WHERE de l'ordre
UPDATE afin de filtrer de manire plus complte.
Par exemple, afin d'viter de confondre des prospects qui ont
le mme nom et prnom que certains client, on dsire ajouter
le mot "bis" aux prospects homonymes :
exemple 23
UPDATE T_PROSPECT
SET PRP_NOM = TRIM(RIGHT, PRP_NOM) || ' bis'
WHERE PRP_ID = (SELECT PRP_ID
FROM T_PROSPECT P
JOIN T_CLIENT C
ON C.CLI_NOM = P.PRP_NOM
AND C.CLI_PRENOM= P.PRP_PRENOM)
mZWULW :
Une mise jour peut chouer si elle viole les contraintes.
Voici les principaux cas pour lesquels un ordre de
modification ne peut aboutir :
violation de clef (index primaire)
violation de contrainte d'index secondaire unique
violation de contrainte de donnes (colonne not null)
violation d'intgrit rfrentielle
violation de contrainte de contrle de validit (min,
max, tendue, domaine...)

Vous aimerez peut-être aussi