Comandos sql e exercicios avançados

Download Comandos sql e exercicios avançados

Post on 08-Aug-2015

419 views

Category:

Documents

2 download

Embed Size (px)

DESCRIPTION

dddddd

TRANSCRIPT

<p>Juno de Tabelas</p> <p>A figura abaixo resume as operaes de juno:</p> <p>As operaes de juno dividem-se em dois grupos: horizontais e verticais. As horizontais actuam sobre linhas enquanto as verticais actuam sobre colunas. Juno horizontal Utiliza-se uma juno horizontal quando a consulta SQL requer dados de duas ou mais tabelas. Esta a operao que na prtica tira partido do conceito "base de dados relacional" pois permite mostrar os dados que esto armazenados em diferentes tabelas como se estivessem armazenados numa nica, desde que essas tabelas possuam um relacionamento entre si. A tabela resultado construda a partir de uma das tabelas originais, acrescentando colunas da segunda tabela, o que corresponde a um crescimento horizontal. A norma SQL99 define a sintaxe usada pelas clusulas do comando SELECT para fazer os diferentes tipos de juno. A base de dados Oracle suporta esta sintaxe desde a verso 9.0. Nas verses anteriores 9.0 era usada uma sintaxe antiga, que no caso da juno externa possuia uma notao proprietria. Por razes de compatibilidade com o passado a sintaxe antiga com as extenses</p> <p>proprietrias contnua disponvel. Neste manual os comandos sero dados seguindo as duas abordagens: sintaxe antiga e SQL99.</p> <p>Produto cartesiano</p> <p>O produto cartesiano entre dois conjuntos um terceiro conjunto constitudo por todos os elementos do primeiro combinados com todos os elementos do segundo. Os comandos abaixo geram o produto cartesiado entre as tabelas EMP e DEP: Sintaxe antigaSELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname FROM emp, dept; EMPNO ENAME DNAME ---------------------- ------------------ -------------7369 SMITH ACCOUNTING 7499 ALLEN ACCOUNTING 7521 WARD ACCOUNTING 7566 JONES ACCOUNTING 7654 MARTIN ACCOUNTING 7698 BLAKE ACCOUNTING 7782 CLARK ACCOUNTING 7788 SCOTT ACCOUNTING 7839 KING ACCOUNTING 7844 TURNER ACCOUNTING 7876 ADAMS ACCOUNTING 7900 JAMES ACCOUNTING 7902 FORD ACCOUNTING 7934 MILLER ACCOUNTING 7369 SMITH RESEARCH</p> <p>SQL99SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname FROM emp CROSS JOIN dept; DEPTNO DEPTNO</p> <p>---------------------- ------------20 30 30 20 30 30 10 20 10 30 20 30 20 10 20 10 10 10 10 10 10 10 10 10 10 10 10 10 10 20</p> <p>7499 RESEARCH 7521 RESEARCH 7566 RESEARCH 7654 RESEARCH 7698 RESEARCH 7782 RESEARCH 7788 RESEARCH 7839 RESEARCH 7844 RESEARCH 7876 RESEARCH 7900 RESEARCH 7902 RESEARCH 7934 RESEARCH 7369 SALES 7499 SALES 7521 SALES 7566 SALES 7654 SALES 7698 SALES 7782 SALES 7788 SALES 7839 SALES 7844 SALES 7876 SALES 7900 SALES 7902 SALES 7934 SALES 7369 OPERATIONS 7499 OPERATIONS 7521 OPERATIONS 7566</p> <p>ALLEN WARD JONES MARTIN BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER SMITH ALLEN WARD JONES MARTIN BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER SMITH ALLEN WARD JONES</p> <p>30 30 20 30 30 10 20 10 30 20 30 20 10 20 30 30 20 30 30 10 20 10 30 20 30 20 10 20 30 30 20</p> <p>20 20 20 20 20 20 20 20 20 20 20 20 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 40 40 40 40</p> <p>OPERATIONS 7654 OPERATIONS 7698 OPERATIONS 7782 OPERATIONS 7788 OPERATIONS 7839 OPERATIONS 7844 OPERATIONS 7876 OPERATIONS 7900 OPERATIONS 7902 OPERATIONS 7934 OPERATIONS 56 rows selected</p> <p>MARTIN BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER</p> <p>30 30 10 20 10 30 20 30 20 10</p> <p>40 40 40 40 40 40 40 40 40 40</p> <p>Na sintaxe proprietria o produto cartesiano obtido quando se faz referencia a mais que duas tabelas e no se coloca uma condio de JOIN na clusula WHERE; Na sintaxe SQL99 o produto cartesiano obtido usando a clusula CROSS JOIN; A sintaxe SQL99 menos susceptvel a erros, pois preciso usar explicitamente a clusula CROSS JOIN, enquanto que na sintaxe proprietria, se houver esquecimento da clusula de JOIN ou erro na sua construo, sai um produto cartesiano; O resultado do produto cartesiano raramente til, pois mostra combinaes de linhas que no tm relao entre si e por isso no so teis para o utilizador. A sua execuo causa muito I/O na base de dados;</p> <p>Juno Interna</p> <p>Sumrio</p> <p>A juno interna uma operao de juno horizontal entre duas tabelas, que usa uma comparao por igualdade entre a(s) coluna(s) comum(ns). Normalmente a(s) coluna(s) comum(ns) (so) Foreign Key numa tabela e Primary Key ou Unique Key na outra. A juno interna pode ser vista como um produto cartesiano filtrado, pois exige que as linhas da tabela da esquerda tenham correspondente na tabela da direita, sendo o valor da coluna comum igual. O diagrama apresentado a seguir mostra como funciona a juno interna entre duas tabelas:</p> <p>A juno interna a operao mais importante nas bases de dados relacionais, pelo que suportada desde sempre. A norma SQL99 propos uma nova sintaxe para esta operao, tendo disponibilizado vrias clusulas que sero analisadas nos exemplos abaixo, onde tambm faremos a comparao com a sintaxe antiga. Os temas abordados sero: </p> <p>Clusula ON Clusula USING Clusula NATURAL JOIN Comparao entre ON, USING e NATURAL JOIN Sinnimos para nomes de tabelas Juno com mais de duas tabelas A clusula de juno e a clusula de filtro A juno feita com coluna(s) UNIQUE</p> <p>Clusula ON As tabelas EMP e DEPT possuem uma relao entre si, implementada atravs da coluna comum DEPTNO. Na tabela EMP sabemos qual o nmero do departamento em que o empregado trabalha. Na tabela DEPT sabemos o nmero, nome e localizao desse departamento. Para juntar os dois conjuntos efectuamos uma JUNO horizontaldas duas tabelas, usando uma igualdade de valores na coluna comum, como ilustrado nos exemplos abaixo:</p> <p>Sintaxe antigaSELECT emp.empno,</p> <p>SQL99SELECT emp.empno,</p> <p>emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno;</p> <p>emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp INNER JOIN dept ON (emp.deptno=dept.deptno); DEPTNO ------------20 30 30 20 30 30 10 20 10 30 20 30 20 10</p> <p>EMPNO ENAME DEPTNO DNAME LOC ---------------------- ---------- ------------------------------ -------------- ------------7369 SMITH 20 RESEARCH DALLAS 7499 ALLEN 30 SALES CHICAGO 7521 WARD 30 SALES CHICAGO 7566 JONES 20 RESEARCH DALLAS 7654 MARTIN 30 SALES CHICAGO 7698 BLAKE 30 SALES CHICAGO 7782 CLARK 10 ACCOUNTING NEW YORK 7788 SCOTT 20 RESEARCH DALLAS 7839 KING 10 ACCOUNTING NEW YORK 7844 TURNER 30 SALES CHICAGO 7876 ADAMS 20 RESEARCH DALLAS 7900 JAMES 30 SALES CHICAGO 7902 FORD 20 RESEARCH DALLAS 7934 MILLER 10 ACCOUNTING NEW YORK 14 rows selected</p> <p>Com esta operao o utilizador consegue visualizar o nome do empregado, o nome do departamento em que trabalha e a sua localizao, ou seja, v os dados de duas tabelas relacionadas como se fossem uma nica; Esta juno pode ser interpretada como um produto cartesiano ao qual foram eliminadas as linhas que no satisfazem a condio de juno; O comentrio anterior mostra como interpretar a juno em comparao com o produto cartesiano, mas no revela a forma como o</p> <p>motor da base de dados efectivamente resolve a operao. Esta operao to importante que os construtores de motores relacionais investem muitos recursos para optimizar o desempenho, o que resulta na existncia de vrios meios para executar a juno, que dependem da dimenso das tabelas envolvidas, da existncia de ndices e da selectividade das colunas comuns. Produzir um produto cartesiano e depois filtrar linhas um meio muito dispendioso em termos de I/O e processamento, pelo que os motores recorrem a outros caminhos, cuja explicao mais detalhada est fora do mbito deste curso; As tabelas DEPT e EMP tm em comum a coluna DEPTNO pelo que nos comandos houve necessidade de distinguir de qual das tabelas queremos obter a coluna. Sempre que h ambiguidade nos nomes das colunas o utilizador obrigado a indicar o nome da tabela a que pertence a coluna pretendida. Por exemploEMP.DEPTNO e DEPT.DEPTNO; A maioria das operaes de juno so internas (INNER) pelo que a palavra reservada INNER facultativa;</p> <p>Topo</p> <p>Clusula USING A clusula USING est disponvel na sintaxe SQL99 e pode ser usada em vez da clusula ON sempre que a(s) coluna(s) usada(s) na juno tenha(m) o mesmo nome em ambas as tabelas. Esta clusula pode ser usada mesmo que existam outras colunas com o mesmo nome em ambas as tabelas. No caso das tabelas EMP e DEPT a juno pode ser feita com USING: Sintaxe antigaSELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno;</p> <p>SQL99SELECT emp.empno, emp.ename, deptno, dept.dname, dept.loc FROM emp INNER JOIN dept USING (deptno);</p> <p>Esta clusula facilita a escrita do query, mas requer a validao prvia de que a(s) coluna(s) usada(s) na juno tem(m) o mesmo nome em ambas as tabelas; A clusula USING obriga a que a(s) coluna(s) usada(s) na juno seja(m) referenciada(s) sem o nome da tabela a que pertence(m);</p> <p>Topo</p> <p>Clusula NATURAL JOIN A clusula NATURAL JOIN est disponvel na sintaxe SQL99 e pode ser usada em vez da clusula ON ou em vez da clusula USING sempre que: </p> <p>A(s) coluna(s) usada(s) na juno tenha(m) o mesmo nome em ambas as tabelas; A(s) coluna(s) usada(s) na juno (so) a(s) nica(s) com o mesmo nome em ambas as tabelas;</p> <p>No caso das tabelas EMP e DEPT a juno pode ser feita com NATURAL JOIN: Sintaxe antigaSELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno;</p> <p>SQL99SELECT emp.empno, emp.ename, deptno, dept.dname, dept.loc FROM emp NATURAL JOIN dept;</p> <p>Esta clusula facilita a escrita do query pois o utilizador no tem que referir qual(ais) a(s) coluna(s) que vai usar na juno; Esta clusula requer a validao prvia no s de que a(s) coluna(s) usada(s) na juno tem(m) o mesmo nome em ambas as tabelas mas tambm que (so) a(s) nica(s) coluna(s) comum(ns); A clusula NATURAL JOIN obriga a que a(s) coluna(s) usada(s) na juno seja(m) referenciada(s) sem o nome da tabela a que pertence(m);</p> <p>Topo</p> <p>Comparao entre ON, USING e NATURAL JOIN Consideremos as seguintes situaes: NAT URA USIN L G JOI NSELECT * FROM t1 INNER JOIN t2 USING (t1_c1 ); SELECT * FROM t3 INNER JOIN t4 USING (t3_c1 ,t3_c2 ); SELE CT * FROM t1 NATU RAL JOIN t2;</p> <p>Sit ua o</p> <p>Modelo entidade relacionamento</p> <p>Sintaxe antiga</p> <p>ON</p> <p>1</p> <p>SELECT * FROM t1, t2 WHERE t1.t1_c1 =t2.t1_c 1;</p> <p>SELECT * FROM t1 INNER JOIN t2 ON (t1.t1_c 1=t2.t1_ c1); SELECT * FROM t3 INNER JOIN t4 ON (t3.t3_c 1=t4.t3_ c1 AND t3.t3_c2 =t4.t3_c 2); SELECT * FROM t5 INNER JOIN t6 ON (t5.t5_c 1=t6.t6_ c2);</p> <p>2</p> <p>SELECT * FROM t3, t4 WHERE t3.t3_c1 =t4.t3_c 1 AND t3.t3_c2 =t4.t3_c 2;</p> <p>SELE CT * FROM t3 NATU RAL JOIN t4;</p> <p>3</p> <p>SELECT * FROM t5, t6 WHERE t5.t5_c1 =t6.t6_c 2;</p> <p>No No possv poss el velSELECT * FROM t7 INNER JOIN t8 USING (t7_c1 );</p> <p>4</p> <p>SELECT * FROM t7, t8 WHERE t7.t7_c1 =t8.t7_c 1;</p> <p>SELECT * FROM t7 INNER JOIN t8 ON (t7.t7_c 1=t8.t7_ c1);</p> <p>No poss vel</p> <p>Topo</p> <p>Sinnimos para nomes de tabelas O nome da tabela pode ser substitudo por um sinnimo, como mostram os exemplos abaixo: Sintaxe antigaSELECT e.empno, e.ename, e.deptno, d.deptno, d.dname, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno;</p> <p>SQL99SELECT e.empno, e.ename, e.deptno, d.deptno, d.dname, d.loc FROM emp e INNER JOIN dept d ON (e.deptno=d.deptno);</p> <p>A utilizao de sinnimos para os nomes das tabelas apresenta as seguintes vantagens: </p> <p>Ajuda a distinguir as colunas que tm o mesmo nome nas duas tabelas. O mesmo fim pode ser atingido usando o nome da tabela; O query mais rapidamente interpretado pela base de dados, pois esta no tem duvidas de onde tem que ir buscar as colunas, pelo que poupa processamento. Este fim tambm pode ser atingido recorrendo ao nome da tabela; Permite efectuar a juno de uma tabela com ela prpria;</p> <p>Topo</p> <p>Juno com mais de duas tabelas A figura abaixo mostra as relaes existentes entre as tabelas EMPLOYEES, DEPARTMENTS e LOCATIONS, pertencentes ao conjunto HR:</p> <p>Este relacionamento possibilita a juno entre as 3 tabelas exemplificada pelos comandos abaixo: Sintaxe antiga ON USINGSELECT e.first_name , e.last_name, SELECT e.first_name, e.last_name, d.department_id, d.department_name, l.city, l.state_province FROM employees e, departments d, locations l WHERE e.department_id=d.dep artment_id AND d.location_id=l.locat ion_id; SELECT e.first_name, e.last_name, d.department_id, d.department_name, l.city, l.state_province FROM employees e INNER JOIN departments d ON (e.department_id=d.depa rtment_id) INNER JOIN locations l ON (d.location_id=l.locati on_id); department_i d, d.department _name, l.city, l.state_prov ince FROM employees e INNER JOIN departments d USING (department_ id) INNER JOIN locations l USING (location_id );</p> <p>NATURA L JOIN</p> <p>No possvel porque a coluna MANAGE R_ID comm a Employees ea Departmen ts e nao usada na clusula de juno deste relacionam ento</p> <p>Na maior parte das situaes vlido o seguinte principio: se h n tabelas temos que usar n-1 condies de juno. Esta regra no vlida quando existe mais que uma relao entre duas tabelas, como no nosso exemplo, casos onde se deve aplicar o princpio abaixo; Cada relacionamento entre duas tabelas exige uma condio de juno. Neste exemplo consideramos o nico relacionamento entre LOCATIONS e DEPARTMENTS e nos vrios relacionamentos existentes entre EMPLOYEES e DEPARTMENTS consideramos apenas EMP_DEPT_FK; A condio de juno deve incluir todas as colunas usadas na juno;</p> <p>Topo</p> <p>A clusula de juno e a clusula de filtro O facto de efectuarmos uma juno entre duas tabelas no impede que se faa um filtro das linhas. O exemplo abaixo mostra como: Sintaxe antiga ON USINGSELECT e.first_name , SELECT e.first_name, e.last_name, d.department_id, d.department_name FROM employees e, departments d WHERE e.department_id=d.depa rtment_id AND e.first_name like 'Jam%'; SELECT e.first_name, e.last_name, d.department_id, d.department_name FROM employees e INNER JOIN departments d ON (e.department_id=d.depa rtment_id) WHERE e.first_name like 'Jam%'; e.last_name, department_i d, d.department _name FROM employees e INNER JOIN departments d USING (department_ id) WHERE e.first_name like '%me%';</p> <p>NATURA L JOIN No possvel porque a coluna MANAGE R_ID comm a Employees ea Department s e nao usada na clusula de juno deste relacionam ento</p> <p>Na sintaxe antiga as condies de juno e de filtro misturam-se, sendo necessria uma leitura mais atenta para as distinguir; Na sintaxe SQL99 h uma separao clara entre condies de juno e de filtro;</p> <p>Topo</p> <p>A juno feita com colunas UNIQUE As boas prticas recomendam que a juno entre duas tabelas seja feita entre a chave primria (PK - Primary Key) de uma e a chave estrangeira (FK Foreign Key) da outra tabela. O motor relacional do Oracle permite que a chave primria seja substituda por uma chave alternativa. Por exemplo, em vez do nmero de empregado poderamos usar o NIF (Nmero de Identificao Fiscal), desde que este seja nico para cada empregado e tenha um valor no nulo. Para isto a base de dados requer a existncia de um ndice com a propriedade UNIQUE ou que seja definida a restrio UNIQUE sobre a(s) coluna(s) envolvida(s).</p> <p>Juno externa</p> <p>O diagrama entidade relacionamento a seguir apresentado...</p>