SQL DML CONSULTAS ENVOLVENDO MAIS DE UMA TABELA Uma consulta envolvendo informações de mais de uma tabela podem ser realizadas por encadeamento ou junção(join). 1. Consultas Encadeadas - SubConsultas Consultas encadeadas, também referenciadas como subconsultas, permitem que uma consulta seja feita sobre o resultado de uma outra consulta. Deve-se empregar esta técnica quando se deseja informações de uma tabela porém, a condição deve ser expressa com campos de outra tabela. Nesta situação o gerenciador de consultas do SGBD executa primeiro as consultas internas e os resultados são comparados segundo o operador de elo entre as consultas. Os predicados de elos entre consultas são: "=", "IN", "EXISTS', ANY( ou SOME) e os operadores relacionais ("<", "<=",">" e ">=") Sintaxes possíveis: WHERE coluna k = (SELECT coluna j WHERE coluna k IN (SELECT coluna j FROM tabela(s) WHERE coluna k ANY (SELECT coluna j WHERE coluna k OPERADOR RELACIONAL ALL (SELECT coluna j Operadores relacionais de comparação: >, >=, < e <= WHERE EXISTS (SELECT * WHERE coluna <operador> tabela1.colunai) Prof. Sidney Vieira 1
= Verifica se o valor do campo que precede o predicado é exatamente o igual ao valor retornado na subconsulta IN Verifica se o valor do campo que precede o predicado faz parte do subconjunto de valores retornados na subconsulta ANY Verifica se o campo que precede o predicado é igual a algum valor retornado na subconsulta EXISTS Verifica se um valor existe um retorno não nulo da subconsulta(*). Neste caso o sql exibirá as linhas da tabela tabela1 que atendem a restrição da subconsulta. A negação do predicado cláusula é definida por NOT EXISTS. Exemplos: ---------------------------------------------------------------------------------------------------------------------- Considere as relações(tabelas) para os exemplos a seguir: DEPARTAMENTO COD NOME ORCAMENTO MATR ======== ================ =================== ================ 1 desenvolvimento 100000.00 2 2 rede 200000.00 7 3 manutencao 80000.00 5 FUNCIONARIO MATR NOME SALARIO ADMISSAO SEXO DEP_COD MATR_SUPERVISOR ====================================================================================================== 1 ze 1000.00 09-DEC-2000 M 1 NULL 2 ana 1500.00 10-NOV-2001 F 1 1 3 pedro 1000.00 21-JAN-2001 M 2 6 4 eva 2000.00 03-DEC-2002 F 1 1 5 ivo 1800.00 10-OCT-2002 M 3 NULL 6 sid 900.00 22-FEB-2002 M 2 NULL 7 ines 1500.00 01-NOV-2003 F 2 5 Obs: o campo matr em DEPARTAMENTO tem a função de guardar a matricula do chefe do departamento o campo DEP_COD em funcionário tem a função de guardar o departamento de alocação do funcionário. o campo MATR_SUPERVISOR em funcionário tem a função de guardar a matricula do supervisor do funcionário os nomes dos funcionários são únicos ou seja não existe dois funcionários com o mesmo nome ------------------------------------------------------------------------------------------------------------------------- Exemplo1: Obter o nome dos funcionários que estão alocados em departamentos com orçamentos inferiores a R$ 90.000,00 Prof. Sidney Vieira 2
WHERE dep_cod IN (SELECT cod FROM departamento WHERE orcamento < 90000) Exemplo2: Obter o nome do departamento cujo chefe é a funcionária de nome ines FROM departamento WHERE matr = (SELECT matr WHERE nome = 'ines') Este exemplo emprega o predicado = pois não existe, conforme descrito anteriormente, dois funcionários com o mesmo nome. Caso existisse deveríamos empregar o predicado IN Exemplo3 : obter a matricula e nome dos funcionários que são supervisionados pelo funcionário de nome ze SELECT matr, nome WHERE matr_supervisor = (SELECT matr WHERE nome = ze) Neste exemplo é admitido que só existe um funcionario Exemplo4: Obter os nomes e salários dos funcionários que possuam o maior valor salario WHERE salario IN (SELECT MAX(salario) ) OU WHERE salario >= (SELECT MAX(salario) ) OU WHERE salario = (SELECT MAX(salario) ) OBS: Só se emprega o predicado "=" quando a consulta interna retorna ZERO ou 1 e somente 1 resultado. Exemplo5: Obter os nomes e salários dos funcionários que ganham mais do que qualquer funcionário do departamento de codigo 1 WHERE salario > ALL (SELECT salario WHERE dep_cod = 1) Prof. Sidney Vieira 3
Exemplo6: Obter os nomes dos funcionários que são chefes de departamentos WHERE EXISTS (SELECT * FROM departamento WHERE matr = funcionario.matr) Exemplo7: Obter os nomes dos funcionários que não são chefes de departamentos WHERE NOT EXISTS (SELECT * FROM departamento WHERE matr = funcionario.matr) Apelidando tabelas É possivel determinar alias para as tabelas em uma consulta. Para isto basta colocar o apelido a ser usado após o nome da tabela na cláusula From SELECT apelido1.campo1_tab1, apelido1.campo n _tab1,... apelido2. campo k _tab2 FROM tab1 apelido1, tab2 apelido2 WHERE apelido1. campo j _tab1 = apelido2. campo l _tab2 AND apelido2. campo t _tab2 = x AND apelido1.campo m _tab1 = y Exemplo: SELECT f.nome, f.salario, d.nome f, departamento d WHERE f.cod = d.cod AND d.nome = rede AND f.sexo = F Consultas com Join Usada quando se deseja informações de mais de uma tabela. Sintaxe: SELECT tabela1.coluna i,, tabela2.coluna n FROM tabelas1 JOIN tabela2 ON tabela1.coluna j, = tabela2.coluna k [WHERE condição(ões)] OBS: nem todos os SGBD aceitam o termo JOIN neste caso deves-se empregar a sintaxe abaixo SELECT tabela1.coluna i,, tabela2.coluna n FROM tabelas1, tabela2 WHERE tabela1.coluna j, = tabela2.coluna k Prof. Sidney Vieira 4
Exemplos: [AND condição(ões)] Obter o nome e salario dos funcionarios com o nome dos respectivos departamentos onde estão alocados SELECT funcionario.nome, funcionario.salario, departmento.nome JOIN departamento ON funcionario.dep_cod = departamento.cod Obter os dados do departamento de rede com os dados de seu respectivo chefe SELECT * JOIN departamento ON funcionario.matr = departamento.matr WHERE departamento.nome = rede SELECT *, departamento WHERE funcionario.matr = departamento.matr AND departamento.nome = rede Obter o nome e orcamento do departamento de redes com o nome e salario dos seus respectivos funcionarios do sexo feminino SELECT departamento.nome, departamento.orcamento, funcionario.nome, funcionario.salario,, departamento WHERE funcionario.dep_cod = departamento.cod AND departamento.nome = rede AND funcionario.sexo = F SELECT d.nome, d.orcamento, f.nome, f.salario, f, departamento d WHERE f.dep_cod = d.cod AND d.nome = rede AND f.sexo = F Prof. Sidney Vieira 5