SQL ernanda Baião UNIRIO aterial parcialmente extraído a partir das notas de aula de aria Luiza. Campos, Arnaldo Rocha e aria Cláudia Cavalcanti SQL Introdução SQL Structured Query Language Linguagem de fato de acesso a BDs relacionais 1970: E. Codd/IB propõe o odelo Relacional 1981: Primeiro produto comercial SQL/DS 1987: ANSI SQL é aceito como padrão ISO 1992: SQL2 - novos tipos e comandos, restrições de integridade SQL:1999 ou SQL3 LOBs, triggers, OO,... SQL:2 table functions, sequenciais, merge,... SQL/XL:2 mapeamento, schema,... 1
SQL ANSI SQL SGBD SQL Vários produtos com diferentes sabores de SQL Acesso direto às bases de dados para consulta, atualização e definição de dados Outras formas de se usar SQL Consulta: comando SELECT Atualização: comandos UPDATE, INSERT, DELETE Definição de dados: comandos CREATE, ALTER, DROP odelo Relacional Um banco de dados relacional contém um ou mais objetos chamados tabelas. As informações estão armazenadas nestas tabelas. As linhas contém dados e são conhecidas como tuplas. A tabela abaixo contém informações sobre a temperatura das cidades. city state high low Phoenix Arizona 105 90 Tucson Arizona 101 92 lagstaff Arizona 88 69 San Diego California 77 60 Albuquerque New exico 80 72 Base de Dados Empresa Superat atrículaemp Depto DEPENDENTE EPREGADO DEPARTAENTO atrículagerente atrículaemp Depto PROJETO TRABALHA_E DEPTO_LOCAL PCódigo 2
A tabela Empregado EPREGADO Nome Snome atrícula DataNasc Endereço Sexo Salário SuperVisor Depto aria João Abel Carlos Edson lávio Gilda Irene José Kátia Noel Otto Silva Goya lores Gardel Celui Altolá Gomes Silva Santos Souza oura Reis Bastos 001 004 005 006 007 008 009 010 011 012 013 13/07/55 23/12/65 31/10/73 11/09/72 21/02/44 30/09/56 01/08/66 15/05/64 16/04/63 25/05/59 22/03/60 03/01/61 01/11/62 NULL 001 001 DG DG DG O comando SELECT SELECT [ALL DISTINCT] lista-de-seleção RO tabela [,tabela]... [WHERE condição ] [GROUP BY atributo(s)] [HAVING condição] [ORDER BY atributo(s)] Tipos de dados do SQL Integer: int, smallint, tinyint loat: float, double, real Char: char(), varchar() Date, Time oney Binary Serial 3
Exemplos de uso do Select 1. Recuperação simples de tabelas SELECT NOE, DATANASC Nome aria João Abel Carlos Edson lávio Gilda Irene José Kátia Noel Otto DataNasc 13/07/55 23/12/65 31/10/73 11/09/72 21/02/44 30/09/56 01/08/66 15/05/64 16/04/63 25/05/59 22/03/60 03/01/61 01/11/62 Exemplos de uso do Select 2. Listar todos os atributos para tuplas obedecendo a uma determinada condição SELECT * WHERE SEXO = ' Nome Snome atrícula DataNasc Endereço Sexo Salário SuperVisor Depto aria Gilda Irene Kátia Silva Gomes Santos oura 001 007 009 011 13/07/55 01/08/66 16/04/63 22/03/60 NULL DG Exemplos de uso do Select 3. Recuperação com a eliminação de tuplas duplicadas SELECT DISTINCT SALÁRIO 4. Recuperação com valores computados de colunas Salário SELECT DISTINCT SALARIO, SALARIO * 1,10 AS Novo Salário Salário Novo Salário 1100 2200 3300 4
Exemplos de uso do Select 5. Ordenando o resultado de uma consulta SELECT NOE,SALARIO ORDER BY NOE Nome Abel Carlos Edson lávio Gilda Irene João José Kátia aria Noel Otto Salário Exemplos de uso do Select 6. Recuperação com condições envolvendo conjuntos e intervalos: Usando IN: SELECT DISTINCT ATRICULA WHERE SUPERVISOR IN (001,) Nome atrícula 005 006 007 010 012 013 Salário Usando BETWEEN: SELECT NOE, SALARIO WHERE SALARIO BETWEEN AND aria João Abel Carlos lávio Gilda José Noel Otto Exemplos de uso do Select 7. Recuperação por aproximação usando LIKE: "_" - uma ocorrência de qualquer caractere, "%" - nenhuma ou várias ocorrências de quaisquer caracteres. SELECT NOE WHERE NOE LIKE J%' Nome João José 8. Usando NULL em comparações: SELECT NOE WHERE SUPERVISOR IS NULL Nome aria 5
Tabelas S, P e SP S (suppliers) S# SNAE STATUS CITY S1 Smith 20 London S2 Jones 10 Paris S3 Blake 30 Paris S4 Clark 20 London S5 Adams 30 Athens P (parts) P# PNAE COLOR WEIGHT CITY P1 Nut Red 12 London P2 Bolt Green 17 Paris P3 Screw Blue 17 Rome P4 Screw Red 14 London P5 Cam Blue 12 Paris P6 Cog Red 19 London SP (fornecimento) S# P# QTY S1 P1 300 S1 P2 200 S1 P3 400 S1 P4 200 S1 P5 100 S1 P6 100 S2 P1 300 S2 P2 400 S3 P2 200 S4 P2 200 S4 P4 300 S4 P5 400 SQL unções de Agregação Exemplos de uso do Select 9. Uso de funções de agregação: SELECT AVG(SALARIO) SELECT AX(SALARIO) SELECT IN(SALARIO) SELECT SU(SALARIO) SELECT COUNT(*) AVG(SALARIO) AX(SALARIO) IN(SALARIO) SU(SALARIO) 26000 COUNT(*) 13 6
Exemplos de uso do Select 10. Agrupando o resultado: SELECT DEPTO, AVG(SALARIO) GROUP BY DEPTO SELECT SUPERVISOR, COUNT(*) GROUP BY SUPERVISOR SELECT SEXO, SU(SALARIO) GROUP BY SEXO Depto AVG(Salario) DG 1333 2250 2167 Supervisor COUNT(*) 001 2 4 6 1 Sexo SU(Salario) 9000 17000 Exemplos de uso do Select 10. Agrupando o resultado: SELECT DEPTO, AVG(SALARIO) GROUP BY DEPTO HAVING AVG(SALARIO) > SELECT SUPERVISOR, COUNT(*) GROUP BY SUPERVISOR HAVING COUNT(*) > 3 SELECT SEXO, SU(SALARIO) GROUP BY SEXO HAVING SU(SALARIO)!= 0 Depto AVG(Salario) 2250 2167 Supervisor COUNT(*) 4 6 Sexo SU(Salario) 9000 17000 Valor Nulo Indica um dado não preenchido, de valor ignorado, ou um campo que não tem valor naquele registro. Não participa nas computações. média (2,4,0 ) = 2 ( 6 / 3 ) média (2,4,NULL) = 3 ( 6 / 2 ) 7
Valor Nulo 11. Observando os valores nulos SELECT COUNT(*) AS Total de empregados, COUNT(SUPERVISOR) AS Total de empregados supervisionados ) Total de Empregados Total de Empregados Supervisionados 13 12 Observações unção_de_agregação( [DISTINCT] expressão) SELECT AVG( DISTINCT SALARIO) ------- Sumariar em mais de um nível não é possível SELECT Depto, Avg(Salario), Supervisor, COUNT(Nome) GROUP BY Depto, Supervisor Group by pode ser usado sem unções de Agregação unciona como se fosse um DISTINCT Group by NÃO necessariamente ordena Having X Where WHERE seleciona as tuplas antes da agregação HAVING seleciona as tuplas depois da agregação SELECT Supervisor, COUNT(*) WHERE Salario > GROUP BY Supervisor SELECT Supervisor, COUNT(*) GROUP BY Supervisor HAVING Salario > Supervisor 3 1 COUNT(*) Supervisor COUNT(*) 4 6 8
SQL Junção União Subconsultas Junções Em várias consultas será necessário correlacionar os dados de várias tabelas. Por exemplo: Qual o nome do depto de cada empregado? Liste os nomes dos empregados de um projeto? Qual o nome dos gerentes de cada departamento? Tabelas do BD Empresa EPREGADO Nome SNome atrícula DataNasc Endereço Sexo Salário Superat Depto DEPARTAENTO DeptoNome DeptoSigla atrículagerente PROJETO PNome PCódigo PLocalização Depto TRABALHA_E atrículaemp PCódigo Horas 9
A tabela Empregado EPREGADO Nome Snome atrícula DataNasc Endereço Sexo Salário SuperVisor Depto aria João Abel Carlos Edson lávio Gilda Irene José Kátia Noel Otto Silva Goya lores Gardel Celui Altolá Gomes Silva Santos Souza oura Reis Bastos 001 004 005 006 007 008 009 010 011 012 013 13/07/55 23/12/65 31/10/73 11/09/72 21/02/44 30/09/56 01/08/66 15/05/64 16/04/63 25/05/59 22/03/60 03/01/61 01/11/62 NULL 001 001 DG DG DG Outras tabelas do BD Empresa DEPARTAENTO DeptoNome DeptoSigla Direção Geral DG Produção Desenvolvimento PROJETO PNome Tamar Jubarte Pantanal PCódigo T J P Gerente 001 PLocalização Itaúnas Abrolhos Bonito Depto TRABALHA_E atrículaemp PCódigo Horas 004 005 006 007 008 009 010 011 012 013 009 010 012 013 P T T J P P P J P P T T J J 40 40 40 40 40 20 20 40 20 20 20 20 20 20 ultiplicação - Produto Cartesiano C1 C2 --------- AA 11 BB 22 C3 C4 --------- 11 ** 22 ## C1 C2 C3 C4 ----------------- AA 11 11 ** AA 11 22 ## BB 22 11 ** BB 22 22 ## 10
Junção C1 C2 --------- AA 11 BB 22 C3 C4 --------- 11 ** 22 ## C2 = C3 C1 C2 C3 C4 ----------------- AA 11 11 ** BB 22 22 ## Em SQL ultiplicação: SELECT * RO DEPARTAENTO, PROJETO Junção: SELECT * RO DEPARTAENTO, PROJETO WHERE PROJETO.Depto = DEPARTAENTO.DeptoSigla Usando apelidos para as tabelas: SELECT * RO DEPARTAENTO d, PROJETO p WHERE p.depto = d.deptosigla Selecionando somente as colunas que interessam: SELECT d.deptonome, p.pnome RO DEPARTAENTO d, PROJETO p WHERE p.depto = d.deptosigla Em SQL Selecionando somente as colunas e tuplas que interessam: Exemplo: Liste o nome do departamento e dos projetos que se localizam em Abrolhos SELECT d.deptonome, p.pnome RO DEPARTAENTO d, PROJETO p WHERE p.depto = d.deptosigla AND p.localização = Abrolhos deptonome pnome ---------------------- Produção Jubarte 11
Tipos de Junção Equijoin: junção baseada na igualdade Self join: junção da tabela com ela mesma Exemplo: Liste os empregados, dois a dois, que possuem o mesmo sobrenome (prováveis parentes) SELECT e1.nome, e2.nome RO empregado e1, empregado e2 WHERE e1.snome = e2.snome e1.nome e2.nome ---------------------- aria aria aria aria Como fazer para evitar as combinações de tuplas iguais? Tipos de Junção Equijoin: junção baseada na igualdade Self join: junção da tabela com ela mesma Exemplo: Liste os empregados, dois a dois, que possuem o mesmo sobrenome (prováveis parentes) SELECT e1.nome, e2.nome RO empregado e1, empregado e2 WHERE e1.snome = e2.snome AND e1.matricula!= e2.matricula e1.nome e2.nome ---------------------- aria aria Como fazer para evitar as duplicatas? Tipos de Junção Equijoin: junção baseada na igualdade Self join: junção da tabela com ela mesma Exemplo: Liste os empregados, dois a dois, que possuem o mesmo sobrenome (prováveis parentes) SELECT e1.nome, e2.nome RO empregado e1, empregado e2 WHERE e1.snome = e2.snome AND e1.matricula < e2.matricula e1.nome e2.nome ---------------------- aria 12
Tipos de Junção Outer Join mostra tuplas que NÃO satisfazem à condição de junção, além das tuplas que satisfazem útil para ver os resultados em contraste com as tuplas que falham muitos fornecedores de SGBD implementaram esta funcionalidade antes do padrão SQL92 sintaxe varia, alguns usam na cláusula WHERE *= inclui todas as tuplas da primeira tabela (left) =* inclui todas as tuplas da segunda tabela (right) Tipos de Junção Exemplo Liste todos os Departamentos e seus projetos, mesmo que o Departamento não possua projeto SELECT d.deptonome, p.pnome RO departamento d, projeto p WHERE d.depto *= p.depto DeptoNome Pnome ----------------------------- Direção Geral NULL Produção Tamar Produção Jubarte Desenvolvimento Pantanal Junção com 3 Tabelas Listar empregados e os projetos em que trabalham 20 horas. SELECT e. Nome, e.snome, p.pnome e, PROJETO p, TRABALHA_E t WHERE e.atricula = t.atriculaemp AND t.pcódigo = p.pcódigo AND t.horas= 20; 13
Subconsultas Sintaxe Simplificada SELECT [DISTINCT] lista_select RO lista_tabelas WHERE {expressão {[NOT] IN operador_comparação [ALL ANY]} [NOT] EXISTS } (SELECT [DISTINCT] lista_subselect RO lista_tabelas WHERE condições) [GROUP BY lista_groupby] [HAVING condições] [ORDER BY lista_orderby] Subconsultas As subconsultas podem ser ou não correlacionadas Não correlacionada: de dentro para fora: a consulta externa baseia-se em valores obtidos pela consulta interna a consulta interna é resolvida primeiro Correlacionada: de fora para dentro: a consulta externa provê valores para que a consulta interna possa ser resolvida para cada tupla resolvida na consulta externa, resolvese a consulta interna Subconsultas SELECT nome, snome RO empregado WHERE matricula IN (SELECT matriculaemp RO trabalha_em WHERE horas = 40) Não Correlacionada A consulta interna é independente Correlacionada A consulta interna é dependente SELECT nome, snome RO empregado e WHERE 40 IN (SELECT horas RO trabalha_em t WHERE t.matriculaemp = e.matricula ) 14
Subconsultas X Junções Subconsultas são apropriadas para consultas que envolvem comparação com agregações ax(salario) SELECT max(salario) ------------ RO empregados SELECT nome,snome RO empregados Nome Snome WHERE salario = ----------------------- Edson Celui Silva SELECT nome,snome Irene Santos RO empregados Katia oura WHERE salario = (SELECT max(salario)ro empregados) Subconsultas X Junções Junções são mais adequadas para resultados que envolvem campos das várias tabelas usadas Exemplo: Liste o nome do projeto e a matrícula dos empregados que trabalham em projetos de 40 horas. SELECT p.pnome,t.matriculaemp RO projetos p WHERE p.pcodigo IN (SELECT t.pcodigo RO trabalha_em t WHERE t.horas = 40) SELECT p.pnome, t.matriculaemp RO projetos p, trabalha_em t WHERE p.pcodigo = t.pcodigo and p.horas = 40 Subconsultas Tipos retornam Zero ou mais itens operador IN ou operador de comparação modificado por ANY/ALL retornam um único valor operador de comparação não modificado são um teste de existência operador EXISTS 15
Subconsultas - [NOT] IN Liste o nome dos empregados que trabalham em projetos com CH =40 horas SELECT e.nome RO empregados e WHERE e.matricula IN (SELECT t.matriculaemp RO trabalha_em t WHERE t.horas = 40) Subconsultas - [NOT] IN Liste o nome dos empregados que Não trabalham em projetos com CH de 40 horas SELECT e.nome RO empregados e WHERE e.matricula NOT IN (SELECT t.matriculaemp RO trabalha_em t WHERE t.horas = 40) Subconsultas - [NOT] IN Relacionar tabelas com elas mesmas pode ser feito de duas maneiras: self-join ou subconsulta Exemplo: Liste os empregados que possuem o mesmo sobrenome que aria SELECT e1.nome RO empregado e1, empregado e2 WHERE e1.snome = e2.snome AND e2.nome = aria AND e2.matricula!= e1.matricula SELECT e1.nome RO empregado e1 WHERE e1.snome IN (SELECT e2.snome RO empregado e2 WHERE e2.nome = aria AND e2.matricula!= e1.matricula) 16
Subconsultas - operador único Subconsultas na cláusula HAVING Exemplo: Encontre os departamentos cujos empregados ganham em média mais que a média salarial geral de todos os empregados SELECT depto RO empregado GROUP BY depto HAVING avg(salario) > (SELECT avg(salario) RO empregado) Subconsultas - operador único Subconsultas correlacionadas Exemplo: Encontre os empregados que ganham mais que a média salarial de seu próprio departamento SELECT nome RO empregado e1 WHERE e1.salario > (SELECT avg(e2.salario) RO empregado e2 WHERE e2.depto = e1.depto) Subconsultas - op [ANY ALL] a > ALL (subconsulta) verdadeiro se a for maior que TODOS os elementos do resultado a > ANY (subconsulta ou consulta) verdadeiro se a for maior que ALGU dos elementos do resultado ou conjunto (em outras palavras, maior que o mínimo) Pode- se usar >, >=, <, <=, = ou!= 17
Subconsultas - op [ANY ALL] Selecionar os empregados que ganham maiores salários que os do departamento de Produção SELECT Nome RO empregado WHERE Salario > ALL (SELECT Salario RO empregado WHERE depto = ) Selecionar os empregados que não ganham salário mínimo SELECT Nome RO empregado WHERE Salario > ANY (SELECT Salario RO empregado) Obs: Quando algum dos valores da subconsulta é NULL o resultado pode não ser apresentado Subconsultas - EXISTS Teste de existência Liste todos os empregados que trabalham no projeto T. SELECT nome RO empregado e WHERE EXISTS (SELECT * RO trabalha_em WHERE matriculaemp = e.matricula AND pcodigo = T ) Subconsultas - EXISTS Teste de inexistência Liste todos os empregados que não trabalham no projeto T. SELECT nome RO empregado e WHERE NOT EXISTS (SELECT * RO trabalha_em WHERE matriculaemp = e.matricula AND pcodigo = T ) 18
Subconsultas - EXISTS Interseção Liste os empregados cujos departamentos possuem Projetos SELECT nome RO empregados e WHERE EXISTS (SELECT * RO projetos p WHERE e.depto = p.depto) Subconsultas - EXISTS Diferença Liste os empregados cujos departamentos não possuem Projetos SELECT nome RO empregados e WHERE NOT EXISTS (SELECT * RO projetos p WHERE e.depto = p.depto) Subconsultas - EXISTS Divisão Liste os empregados que trabalham em todos os projetos SELECT nome RO empregado e WHERE NOT EXISTS (SELECT * RO projetos p WHERE NOT EXISTS (SELECT * RO trabalha_em t WHERE e.matricula = t.matriculaemp and p.codigo = t.pcodigo)) 19
União Podemos unir o resultado de várias consultas, desde que os tipos dos resultados sejam os mesmos Departamentos gerenciados por mulheres e departamentos que atuam em projetos localizados no Espírito Santo SELECT NOE_DEP RO DEPARTAENTO D, EPREGADO E WHERE D.GERENTE = E.#EP AND E.SEXO = '' UNION SELECT NOE_DEP RO DEPARTAENTO D, PROJETO P, WHERE D.NOE_DEP = P.NOE_DEP AND P.PLocalizacao LIKE *,ES* SQL Comandos de atualização Incluindo tuplas INSERT INTO tabela (atributo [,atributo]...) VALUES (constante [,constante]...) ; INSERT INTO tabela (atributo [,atributo]...) operação-select ; Exemplos: INSERT INTO PROJETO (Pcódigo, Pnome, Plocalização, Depto) VALUES (4, ECOBASE, NULL, ); INSERT INTO PROJETO (Pcódigo, Pnome, Plocalização, Depto) SELECT * RO PROJTEP WHERE Depto = ; 20
Alterando tuplas UPDATE tabela SET atributo = expressão [, atributo=expressão]... [WHERE condição] ; Exemplos: UPDATE EPREGADO SET salário = 1,1 * salário; UPDATE PROJETO SET LOCAL = 'BARRA', DATA = '12-01-93' WHERE #PROJ = 12; UPDATE EPREGADO SET SALARIO = SALARIO * 1.1 WHERE NOE_DEP IN (SELECT NOE_DEP RO DEPARTAENTO WHERE NOE_DIR = 'SUPORTE') ; Removendo tuplas DELETE RO tabela [WHERE condição] ; Exemplos: DELETE RO Empregado; DELETE RO PROJTEP WHERE Pcódigo IN (SELECT Pcódigo RO Projeto); Atenção! Sem a cláusula where, remove todas as tuplas! 21