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
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...