INSIA Bases de données ORACLE – 2 – SELECT avancé SQL*Plus

Transcription

INSIA Bases de données ORACLE – 2 – SELECT avancé SQL*Plus
INSIA
Bases de données
ORACLE – 2 – SELECT avancé
SQL*Plus – SQL Developper
http://st-curriculum.oracle.com/tutorial/DBXETutorial/index.htm
http://st-curriculum.oracle.com/
http://www.oracle.com/
Bertrand LIAUDET
SOMMAIRE
SOMMAIRE
SELECT ORACLE AVANCE
WIDTH_BUCKET
WITH
DECODE
CASE
GROUP BY ROLLUP : afficher la somme d’une colonne
GROUP BY CUBE
GROUP BY GROUPING SETS
EXPRESSIONS REGULIERES
Les fonctions utilisant les expressions régulières
Les éléments d’une expression régulière
Exemples
Requêtes hiérarchique : table-arbre : CONNECT BY PRIOR
Présentation
Afficher tous les arbres : CONNECT BY PRIOR enfant = parent
Afficher toutes les branches : CONNECT BY PRIOR parent = enfant
Sélectionner un arbre : START WITH
Sélectionner une branche
Elaguer des branches
Elaguer des arbres
Where classique
Cas des cycles
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 1/13 - Bertrand LIAUDET
1
2
2
2
2
2
3
4
5
6
6
6
6
7
7
7
9
10
10
11
11
12
13
SELECT ORACLE AVANCE
WIDTH_BUCKET
WITDTH_BUCKET (attribut, min, max, nombres d’intervalles) permet de créer un attribut
catégoriel à partir d’un attribut continu.
Exemple
SELECT empno, ename, sal, WIDTH_BUCKET(sal, 0, 10000, 10) tranche
FROM Emp ;
On pourrait écrire
SELECT empno, ename, sal, TRUNC((sal-min)/((max-min)/nbinter))+1
FROM Emp;
WITH
WITH permet de donner un nom à une requête et de pouvoir ensuite l’utiliser comme une table
dans une autre requête.
Exemple
WITH nomReq1 AS (SELECT …) , nomReq2 AS (SELECT …) etc
SELECT … ;
DECODE
DECODE permet de choisir une valeur parmi une liste de valeurs en fonction d’une autre valeur.
Exemple
SELECT empno, ename, hiredate,
DECODE( TRUNC( EXTRACT( YEAR FROM hiredate)/2008), 1, 'NOUVEAU',
0,'ANCIEN') type
FROM Emp;
EXTRACT( YEAR FROM hiredate)/2008) renvoit 1 ou 0.
Selon le résultat, on affiche ‘NOUVEAU” ou “ANCIEN”.
CASE
CASE permet de mettre en place un test dans une requête. C’est un DECODE plus souple.
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 2/13 - Bertrand LIAUDET
Exemple
SELECT empno, ename, hiredate,
CASE EXTRACT (YEAR FROM hiredate)
WHEN 2008 THEN 'Nouveau'
WHEN 2007 THEN ‘Récent’
ELSE ‘Ancien’ END type
FROM Emp;
GROUP BY ROLLUP : afficher la somme d’une colonne
GROUP BY ROLLUP permet de faire un GROUP BY et d’afficher la somme d’une colonne.
Exemples
Select deptno, sum(sal)
from emp
group by rollup(deptno) ;
DEPTNO
SUM(SAL)
---------- ---------10
9550
20
10875
30
9400
29825
Pour avoir la somme des salaires par employés :
Select empno, sum(sal)
from emp
group by rollup(empno);
Avec deux critères de regroupement:
Select job, deptno, count(*), sum(sal)
from emp
group by rollup(job, deptno);
JOB
DEPTNO
COUNT(*)
SUM(SAL)
--------- ---------- ---------- ---------ANALYST
20
2
6000
ANALYST
2
6000
CLERK
10
2
2100
CLERK
20
2
1900
CLERK
30
1
950
CLERK
5
4950
MANAGER
10
1
2450
MANAGER
20
1
2975
MANAGER
30
1
2850
MANAGER
3
8275
PRESIDENT
10
1
5000
PRESIDENT
1
5000
SALESMAN
30
4
5600
SALESMAN
4
5600
15
29825
15 ligne(s) sélectionnée(s).
Noter les totaux intermédiaires.
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 3/13 - Bertrand LIAUDET
GROUP BY CUBE
Le GROUP BY CUBE est utile avec deux critères de regroupement (ou plus). Il donne un bilan
complet : sans critère, par critère simple, par critères couplés.
La différence avec le group by rollup avec deux critères est qu’on a un bilan par critère simple pour les
deux critères et pas pour un seul : dans l’exemple, on a le bilan par DEPTNO en plus (lignes 2, 3 et 4).
Exemple
Select job, deptno, count(*), sum(sal)
from emp
group by cube(job, deptno);
JOB
DEPTNO
COUNT(*)
SUM(SAL)
--------- ---------- ---------- ---------15
29825
10
4
9550
20
5
10875
30
6
9400
ANALYST
2
6000
ANALYST
20
2
6000
CLERK
5
4950
CLERK
10
2
2100
CLERK
20
2
1900
CLERK
30
1
950
MANAGER
3
8275
MANAGER
10
1
2450
MANAGER
20
1
2975
MANAGER
30
1
2850
PRESIDENT
1
5000
PRESIDENT
10
1
5000
SALESMAN
4
5600
SALESMAN
30
4
5600
//
//
//
//
//
//
//
//
//
//
sal des
sal des
sal des
sal des
sal des
sal des
sal des
sal des
sal des
etc.
15 emp
emp du 10
emp du 20
emp du 30
analyst
analyst du20
clerk
clerk du 10
clerk du 20
18 ligne(s) sélectionnée(s).
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 4/13 - Bertrand LIAUDET
GROUP BY GROUPING SETS
Le GROUP BY GROUPING SETS est utile avec deux critères de regroupement (ou plus). Il donne
un bilan complet : il donne un bilan complet pour chaque critère simple. C’est un peu comme si on
fusionnait les résultats de deux GROUP BY.
Exemple
Select job, deptno, count(*), sum(sal)
from emp
group by grouping sets(job, deptno);
JOB
DEPTNO
COUNT(*)
SUM(SAL)
--------- ---------- ---------- ---------CLERK
5
4950
ANALYST
2
6000
PRESIDENT
1
5000
SALESMAN
4
5600
MANAGER
3
8275
30
6
9400
20
5
10875
10
4
9550
8 ligne(s) sélectionnée(s).
A noter le simple GROUP BY :
SQL> Select job, count(*), sum(sal) from emp group by (job);
JOB
COUNT(*)
SUM(SAL)
--------- ---------- ---------CLERK
5
4950
ANALYST
2
6000
PRESIDENT
1
5000
SALESMAN
4
5600
MANAGER
3
8275
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 5/13 - Bertrand LIAUDET
EXPRESSIONS REGULIERES
Les fonctions utilisant les expressions régulières
REGEXP_LIKE (chaîne source, reg-exp) : pour faire des recherches
REGEXP_REPLACE : pour faire des remplacements
REGEXP_SUBSTR :: permet d’extraire une sous-chaîne
REGEXP_INSTR : pour faire des recherches en renvoyant la position trouvée.
REGEXP_COUNT : complète REGEXP_INSTR en comptant le nombre d’occurrences.
Les éléments d’une expression régulière
Élément
\
Description
Le caractère backslash (barre oblique inverse) permet d’annuler l’effet
d’un caractère significatif suivant (opérateur, par exemple).
*
Désigne aucune ou plusieurs occurrences.
+
Désigne une ou plusieurs occurrences.
?
Désigne au plus une occurrence.
|
Opérateur spécifiant une alternative.
^
Désigne le début d’une ligne de caractères.
$
Désigne la fin d’une ligne de caractères.
.
Désigne tout caractère excepté la valeur NULL.
[]
Désigne une liste devant vérifier une expression continue dans la liste. Une
liste ne devant pas vérifier une expression contenue dans la liste devra
commencer par le caractère “^”.
()
Désigne une expression groupée et traitée comme une simple sousexpression.
{m}
Signifie exactement m fois.
{m,}
Signifie au moins m fois.
{m,n}
Signifie au moins m fois mais pas plus de n fois.
[::]
[= =]
Spécifie la classe de caractères (précisée dans le tableau suivant)
Spécifie la classe d’équivalence (ex : '[=a=]' filtrera ä, â, à…).
Exemples
REGEXP_LIKE (date, ‘../../06’);
REGEXP_REPLACE (attribute, ‘(.)’,’\1-‘);
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 6/13 - Bertrand LIAUDET
Requêtes hiérarchique : table-arbre : CONNECT BY PRIOR
Présentation
Les tables avec des auto-jointures peuvent être considérées comme des structures d’arbres.
On part de l’arbre suivant qui décrit l’organigramme d’une entreprise.
7839
7698
7844
7654
7499
7782
7900
7521
7566
7902
7788
7369
7876
Afficher tous les arbres : CONNECT BY PRIOR enfant = parent
Première approche
select level, empno, mgr
l’arbre
from emp
connect by prior empno=mgr;
// « level » : niveeau de l’enfant ds
//
CONNECT BY PRIOR enfant = parent
principe du connect by prior empno=mgr : CONNECT BY PRIOR enfant = parent
« level » est une pseudo-colonne qui donne la « hauteur » de l’enfant ds l’arbre
NIVEAU
EMPNO
MGR
---------- ---------- ---------1
7902
7566
2
7369
7902
1
7788
7566
2
7876
7788
1
7654
7698
1
7499
7698
1
7900
7698
1
7521
7698
1
7844
7698
1
7876
7788
1
7698
7839
2
7654
7698
2
7499
7698
2
7900
7698
2
7521
7698
2
7844
7698
1
7782
7839
1
7566
7839
2
7902
7566
3
7369
7902
2
7788
7566
3
7876
7788
1
7369
7902
1
7839
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 7/13 - Bertrand LIAUDET
2
7698
7839
3
7654
7698
3
7499
7698
3
7900
7698
3
7521
7698
3
7844
7698
2
7782
7839
2
7566
7839
3
7902
7566
4
7369
7902
3
7788
7566
4
7876
7788
36 ligne(s) sélectionnée(s).
Presentation en arbre
select lpad(' ',4*level-4) || empno arbre
from emp
connect by prior empno=mgr;
ARBRE
---------------------------------------------------------------7902
7369
7788
7876
7654
7499
...
7839
7698
7654
7499
7900
7521
7844
7782
7566
7902
7369
7788
7876
36 ligne(s) sélectionnée(s).
La fonction lpad insère une chaîne de caractères à gauche d’une autre.
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 8/13 - Bertrand LIAUDET
Afficher toutes les branches : CONNECT BY PRIOR parent = enfant
SELECT level, empno, mgr
FROM Emp
CONNECT BY PRIOR mgr=empno;
principe du connect by prior empno=mgr : CONNECT BY PRIOR parent = enfant
« level » est une pseudo-colonne qui donne la « hauteur » de l’enfant ds l’arbre
LEVEL
EMPNO
MGR
---------- ---------- ---------1
7369
7902
2
7902
7566
3
7566
7839
4
7839
1
7499
7698
2
7698
7839
3
7839
1
7521
7698
2
7698
7839
3
7839
1
7566
7839
2
7839
1
7654
7698
2
7698
7839
3
7839
1
7698
7839
2
7839
1
7782
7839
2
7839
1
7788
7566
2
7566
7839
3
7839
1
7839
1
7844
7698
2
7698
7839
3
7839
1
7876
7788
2
7788
7566
3
7566
7839
4
7839
1
7900
7698
2
7698
7839
3
7839
1
7902
7566
2
7566
7839
3
7839
level est une pseudo-colonne qui donne le niveau dans l’arbre.
CONNECT BY PRIOR racine=feuille.
Autre presentation:
SQL> select lpad(' ',4*level-4) || empno branches from emp connect
by prior mgr=empno;
BRANCHES
----------------------------------------------------7369
7902
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 9/13 - Bertrand LIAUDET
7566
7839
7499
7698
7839
etc.
La fonction lpad insère une chaîne de caractères à gauche d’une autre.
Sélectionner un arbre : START WITH
select lpad(' ',4*level-4) || empno arbre
from emp
start with empno = 7839
connect by prior empno=mgr;
ARBRE
---------------------------------------------------------------7839
7698
7654
7499
7844
7900
7521
7782
7566
7902
7369
7788
7876
START WITH : l’employé qui sert de racine de l’arbre recherché. Si on filtre avec mgr=7839,
on obtient tous les arbres dont la racine à comme parent le 7839.
Sélectionner une branche
select lpad(' ',4*level-4) || empno branche
from emp
start with empno = 7902
connect by prior mgr=empno;
BRANCHE
-----------------------------------------------------------------7902
7566
7839
START WITH : l’employé qui sert de feuille de la branche recherchée. Si on filtre avec
mgr=7902, on obtient toutes les branches dont les feuilles ont comme parent le 7902.
select level, empno, mgr
from emp
where mgr is not null
start with mgr=7839
connect by prior mgr=empno;
LEVEL
EMPNO
MGR
---------- ---------- ---------1
7566
7839
1
7698
7839
1
7782
7839
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 10/13 - Bertrand LIAUDET
Elaguer des branches
SQL> select lpad(' ',4*level-4) || empno branches from emp connect
by prior mgr=empno and empno !=7566;
BRANCHES
-----------------------------------------------------------------7369
7902
7499
7698
7839
7521
7698
7839
7566
7839
7654
7698
7839
7698
7839
7782
7839
7788
7839
7844
7698
7839
7876
7788
7900
7698
7839
7902
Toutes les branches qui contenaient le 7566 ont été coupées. Le 7566 n’apparaît plus dans les
résultats.
Si on filtre avec mgr=7566, c’est comme si on filtrait avec empno=mgr(7566).
Elaguer des arbres
Couper le lien au parent
SQL> select lpad(' ',4*level-4) || empno arbres from emp connect by
prior empno=mgr and empno !=7566;
ARBRES
-----------------------------------------------------------------7902
7369
7788
7876
7654
7499
7900
7521
7844
7876
7698
7654
7499
7900
7521
7844
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 11/13 - Bertrand LIAUDET
7782
7566
7902
7369
7788
7876
7369
7839
7698
7654
7499
7900
7521
7844
7782
Le 7566 n’apparaît plus comme nœud non racine. Il apparaît quand même comme nœud racine.
Couper les liens aux enfants
SQL> select lpad(' ',4*level-4) || empno arbres from emp connect by
prior empno=mgr and mgr !=7566;
ARBRES
-----------------------------------------------------------------7902
7369
7788
7876
7654
7499
7900
7521
7844
7876
7698
7654
7499
7900
7521
7844
7782
7566
7369
7839
7698
7654
7499
7900
7521
7844
7782
7566
Le 7566 est toujours enfant du 7839 mais il n’est parent de personne.
Where classique
SQL> select lpad(' ',4*level-4) || empno arbres from emp where
deptno!=30 connect by prior empno=mgr and mgr !=7566;
Le WHERE se place juste après le FROM, juste avant le START WITH
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 12/13 - Bertrand LIAUDET
Cas des cycles
Dans l’exemple précédent, relions la racine à n’importe quel autre nœud
Update emp set mgr=7521 where empno=7839
Afficher toutes les branches
SQL> select lpad(' ',4*level-4) || empno hierarchie from emp
connect by prior mgr=empno;
ERROR:
ORA-01436: boucle CONNECT BY dans les données utilisateur
CONNECT BY NOCYCLE PRIOR
SQL> select lpad(' ',4*level-4) || empno branches from emp connect
by nocycle prior mgr=empno;
BRANCHES
-----------------------------------------------------------------7369
7902
7566
7839
7521
7499
7698
7839
7521
7698
7839
7566
7839
7521
7654
7698
7839
etc.
Le 7521 est à la fois feuille et racine.
CONNECT BY IS CYCLE
SQL> select level, empno, mgr, connect_by_iscycle from emp connect
by nocycle prior mgr=empno;
LEVEL
EMPNO
MGR CONNECT_BY_ISCYCLE
---------- ---------- ---------- -----------------1
7369
7902
0
2
7902
7566
0
3
7566
7839
0
4
7839
7521
0
5
7521
7698
1
1
7499
7698
0
2
7698
7839
0
3
7839
7521
1
1
7521
7698
0
2
7698
7839
0
3
7839
7521
1
1
7566
7839
0
2
7839
7521
0
3
7521
7698
1
1
7654
7698
0
2
7698
7839
0
3
7839
7521
1
etc.
INSIA - BASES DE DONNÉES – ORACLE - 02 - page 13/13 - Bertrand LIAUDET

Documents pareils

INSIA – SIGL 2 Bases de données SQL – ORACLE TP 2 DDL et

INSIA – SIGL 2 Bases de données SQL – ORACLE TP 2 DDL et Remarque : le tri oblige à faire une imbrication de select sinon le rownum se fait avant le tri. La restriction oblige à faire une deuxième imbrication de select car le rownum ne permet que de pren...

Plus en détail