BCD29008 Banco de Dados Consulta sobre múltiplas relações Prof. Emerson Ribeiro de Mello Instituto Federal de Santa Catarina IFSC campus São José mello@ifsc.edu.br http://docente.ifsc.edu.br/mello/bcd 11 de setembro de 2017 1/40
MySQL Funções para manipulação de datas 2/40
MySQL: Tipos de dados para data e hora Tipo Descrição DATE Para valores que só possuem data faixa: 1000-01-01 até 9999-12-31. DATETIME Para valores que possuem data e hora faixa: 1000-01- 01 00:00:00 até 9999-12-31 23:59:59 TIMESTAMP Para valores que possuem data e hora faixa: 1970-01- 01 00:00:01 UTC até 2038-01-19 03:14:07 UTC Funções do MySQL para manipular data e hora https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html 2/40
MySQL: Funções DATE FORMAT e TIME FORMAT Máscara Descrição Exemplo %m mês 01,..., 12 %c mês 1,..., 12 %M mês por extenso janeiro,..., dezembro %d dia do mês 01,..., 31 %e dia do mês 1,..., 31 %Y ano - 4 dígitos 2012, 2013,... %y ano - 2 dígitos 12, 13,... %h hora - 12h 01,..., 12 %H hora - 24h 00,..., 23 %i minuto 0,..., 59 %s segundo 0,..., 59 %W dia da semana domingo,..., sábado mysql> select @@lc_time_names; -- verificando atual localizaç~ao mysql> set lc_time_names = 'pt_br'; -- definindo localizaç~ao para pt_br mysql> charset utf8; -- definindo codificaç~ao para utf8 3/40
MySQL: Funções DATE FORMAT e TIME FORMAT SELECT DATE_FORMAT('2017-03-31', '%e %M %Y'); -- 31 março 2017 SELECT DATE_FORMAT('2017-03-29', '%d/%m/%y'); -- 29/03/2017 SELECT TIME_FORMAT('15:40:00', '%Hh %im %ss'); -- 15h 40m 00s SELECT CURRENT_DATE(); -- 2017-03-29 SELECT CURRENT_TIME(); -- 15:40:00 SELECT NOW(); -- 2017-03-29 15:40:00 SELECT DATEDIFF(CURRENT_DATE(), '2017-02-08'); -- valor em dias 4/40
MySQL: Funções DATE ADD e DATE SUB dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function date-add Funções para realização de operações aritméticas com datas (soma e subtração) DATE_ADD( data, INTERVAL expr unidade) ou DATE_SUB(...) -- unidades: MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR Exemplos SELECT DATE_ADD('2017-03-31 15:40', INTERVAL 2 HOUR); --... 17:40:00 SELECT DATE_SUB('2017-03-31 15:40', INTERVAL 1 YEAR); -- 2016-03-31... SELECT DATE_ADD('2017-03-31 15:40:00', INTERVAL '1 2' DAY_HOUR); -- 2017-04-01 17:40:00 SELECT Nome FROM Aluno WHERE CURRENT_DATE() > (DATE_ADD(DIngresso, INTERVAL 9 YEAR)); 5/40
Operações com conjuntos Operador UNION (SELECT... ) UNION (SELECT...) Operador INTERSECT (MySQL não possui esse operador) (SELECT... ) INTERSECT (SELECT...) Operador EXCEPT (MySQL não possui esse operador) (SELECT... ) EXCEPT (SELECT...) Cada consulta deverá possuir o mesmo número de colunas e devem seguir a mesma ordem. Ex: (... nome, cidade... ) UNION (... nome, cidade... ) 6/40
Esquema usado nos próximos exemplos 7/40
Operações com conjuntos Listar o ID de todos os clientes que possuam um empréstimo, uma conta ou ambos Listar o ID de todos os clientes que são correntistas e que possuam um empréstimo Listar o ID de todos os clientes que são correntistas e que não possuam um empréstimo 8/40
Operações com conjuntos Listar o ID de todos os clientes que possuam um empréstimo, uma conta ou ambos (SELECT idpessoa FROM Correntista) UNION (SELECT idpessoa FROM Mutuario) Listar o ID de todos os clientes que são correntistas e que possuam um empréstimo Listar o ID de todos os clientes que são correntistas e que não possuam um empréstimo 8/40
Operações com conjuntos Listar o ID de todos os clientes que possuam um empréstimo, uma conta ou ambos (SELECT idpessoa FROM Correntista) UNION (SELECT idpessoa FROM Mutuario) Listar o ID de todos os clientes que são correntistas e que possuam um empréstimo (SELECT idpessoa FROM Correntista) INTERSECT (SELECT idpessoa FROM Mutuario) Listar o ID de todos os clientes que são correntistas e que não possuam um empréstimo 8/40
Operações com conjuntos Listar o ID de todos os clientes que possuam um empréstimo, uma conta ou ambos (SELECT idpessoa FROM Correntista) UNION (SELECT idpessoa FROM Mutuario) Listar o ID de todos os clientes que são correntistas e que possuam um empréstimo (SELECT idpessoa FROM Correntista) INTERSECT (SELECT idpessoa FROM Mutuario) Listar o ID de todos os clientes que são correntistas e que não possuam um empréstimo (SELECT idpessoa FROM Correntista) EXCEPT (SELECT idpessoa FROM Mutuario) 8/40
Operações com conjuntos O comportamento padrão do operador UNION é de remover tuplas duplicadas da relação resultante Operador ALL permite tuplas duplicadas na relação resultante (SELECT idpessoa FROM Correntista) UNION ALL (SELECT idpessoa FROM Mutuario) Operador IN permite verificar se o valor de um atributo está contido em um conjunto SELECT idagencia, nome FROM Agencia WHERE cidade IN ('S~ao José', 'Florianópolis'); Poderia ser usado para ter o comportamento o INTERSECT. (veja subconsultas aninhadas) Operador EXISTS poderia ser usado para ter o comportamento do EXCEPT 9/40
Valores nullos (NULL) Valor do atributo é desconhecido ou ainda não existe Listar os empréstimos que tenham nulo no atributo valor SELECT idemprestimo FROM Emprestimo WHERE valor IS NULL Resultado de operações aritméticas com nulo sempre será nulo SELECT 5 + NULL; -- retorna NULL Operações de agregação (i.e. SUM, COUNT) ignoram nulos Com exceção do COUNT(*) -- total de linhas cujo valor no atributo cidade n~ao seja NULO SELECT COUNT(cidade) FROM Agencia; -- total de linhas da relaç~ao SELECT COUNT(*) FROM Agencia; 10/40
Valores nullos (NULL) Operadores lógicos Qualquer comparação com valores nulos sempre resultará em nulo SELECT (123 < NULL); SELECT (NULL = NULL); SELECT (NULL <> NULL); Operador lógico OR SELECT (NULL OR TRUE); -- TRUE SELECT (NULL OR FALSE); -- NULL SELECT (NULL OR NULL); -- NULL Operador lógico AND SELECT (NULL AND TRUE); -- NULL SELECT (NULL AND FALSE); -- FALSE SELECT (NULL AND NULL); -- NULL Operador lógico NOT SELECT (NOT NULL); -- NULL 11/40
Esquema usado nos próximos exemplos 12/40
Consulta sobre múltiplas relações +---------------+-----------+-------------+----------------+ idfuncionario Nome Sobrenome iddepartamento +---------------+-----------+-------------+----------------+ 123 Julio Silva 1 326 Jo~ao Silveira 2 331 George de la Rocha 3 332 José Oliveira 1 +---------------+-----------+-------------+----------------+ +----------------+---------------------------+-------------+ iddepartamento Nome Orcamento +----------------+---------------------------+-------------+ 1 Financeiro 15000 2 TI 60000 3 Gest~ao de Pessoas 150000 +----------------+---------------------------+-------------+ Como obter o nome e sobrenome de todos os funcionários, juntamente com os nomes dos departamentos onde estão lotados? 13/40
Consulta sobre múltiplas relações Selecionando colunas de mais de uma relação (Produto cartesiano) SELECT Nome, Sobrenome, dnome FROM Funcionario, Departamento; +-----------+-------------+----------------------------+ Nome Sobrenome dnome +-----------+-------------+----------------------------+ Julio Silva Financeiro Julio Silva TI Julio Silva Gest~ao de Pessoas Arnaldo Coelho Financeiro... for each tupla t 1 in relaç~ao r 1 for each tupla t 2 in relaç~ao r 2... for each tupla t m in relaç~ao r m Concatene t 1, t 2,..., t m em uma única tupla t Adicione t à relaç~ao resultante 14/40
Condições de junção: NATURAL JOIN SELECT Nome, Sobrenome, dnome FROM Funcionario NATURAL JOIN Departamento; +-----------+-------------+--------------------+ Nome Sobrenome dnome +-----------+-------------+--------------------+ Julio Silva Financeiro Arnaldo Coelho Financeiro George de la Rocha Gest~ao de Pessoas... Requer uma coluna com nome comum em todas as relações No exemplo, as relações Funcionário e Departamento possuem uma coluna chamada iddepartamento Combina todas as tuplas que possuem valores iguais na coluna de nome comum 15/40
Condições de junção: INNER JOIN (ou simplesmente JOIN) Retorna registros que possuam valores correspondentes em ambas tabelas SELECT colunas FROM tabela1 INNER JOIN tabela2 ON tabela.colunaa = tabela.colunab; -- Exemplo SELECT f.nome, d.dnome FROM Funcionario f INNER JOIN Departamento d ON f.iddepartamento = d.iddepartamento 16/40
Condições de junção: INNER JOIN Retorna a coluna iddepartamento uma única vez SELECT * FROM Funcionario NATURAL JOIN Departamento; Retorna a coluna iddepartamento duas vezes, uma de cada relação SELECT * FROM Funcionario f INNER JOIN Departamento d ON f.iddepartamento = d.iddepartamento Semelhante ao INNER JOIN, retorna a coluna iddepartamento duas vezes SELECT * FROM Funcionario, Departamento WHERE Funcionario.idDepartamento = Departamento.idDepartamento; 17/40
Usar ON ou WHERE nas consultas com múltiplas relações? Em junções internas, pode-se usar a condição ON ou WHERE Na cláusula FROM, a vírgula (,) seria equivalente ao JOIN SELECT f.nome, d.dnome FROM Funcionario f, Departamento d WHERE f.iddepartamento = d.iddepartamento; SELECT f.nome, d.dnome FROM Funcionario f JOIN Departamento d ON f.iddepartamento = d.iddepartamento 18/40
Usar ON ou WHERE nas consultas com múltiplas relações? Em junções internas, pode-se usar a condição ON ou WHERE Na cláusula FROM, a vírgula (,) seria equivalente ao JOIN SELECT f.nome, d.dnome FROM Funcionario f, Departamento d WHERE f.iddepartamento = d.iddepartamento; SELECT f.nome, d.dnome FROM Funcionario f JOIN Departamento d ON f.iddepartamento = d.iddepartamento Contudo, a consulta SQL pode ser mais legível se usar ON como condição de junção e as demais condições na cláusula WHERE SELECT f.nome, d.dnome FROM Funcionario f JOIN Departamento d ON f.iddepartamento = d.iddepartamento WHERE Orcamento > 13500; Como reescrever a instrução acima usando somente WHERE? 18/40
Usar ON ou WHERE nas consultas com múltiplas relações? Em junções internas, pode-se usar a condição ON ou WHERE Na cláusula FROM, a vírgula (,) seria equivalente ao JOIN SELECT f.nome, d.dnome FROM Funcionario f, Departamento d WHERE f.iddepartamento = d.iddepartamento; SELECT f.nome, d.dnome FROM Funcionario f JOIN Departamento d ON f.iddepartamento = d.iddepartamento Contudo, a consulta SQL pode ser mais legível se usar ON como condição de junção e as demais condições na cláusula WHERE SELECT f.nome, d.dnome FROM Funcionario f JOIN Departamento d ON f.iddepartamento = d.iddepartamento WHERE Orcamento > 13500; Em junções externas, condições ON se comportam de maneira diferente das condições com WHERE 18/40
Junções externas (outer join) Com a junção natural não serão exibidas todas as duplas de Departamento que não tiverem um Funcionário associado SELECT * FROM Departamento NATURAL JOIN Funcionario; 19/40
Junções externas (outer join) Com a junção natural não serão exibidas todas as duplas de Departamento que não tiverem um Funcionário associado SELECT * FROM Departamento NATURAL JOIN Funcionario; Junções externas Preserva as tuplas que seriam perdidas em um junção, criando na relação resultante tuplas que contêm valores nulos 19/40
Junções externas (outer join) Com a junção natural não serão exibidas todas as duplas de Departamento que não tiverem um Funcionário associado SELECT * FROM Departamento NATURAL JOIN Funcionario; Junções externas Preserva as tuplas que seriam perdidas em um junção, criando na relação resultante tuplas que contêm valores nulos Left outer join preserva somente as tuplas da relação à esquerda Right outer join preserva somente as tuplas da relação à direita Full outer join preserva as tuplas das duas relações 19/40
Condições de junção: LEFT JOIN Retorna todas as tuplas da relação à esquerda, mesmo aquelas que não possuam correspondentes na tabela à direita SELECT colunas FROM tabela1 LEFT JOIN tabela2 ON tabela.colunaa = tabela.colunab; -- Exemplo SELECT * FROM Departamento d LEFT JOIN Funcionario f ON d.iddepartamento = f.iddepartamento; SELECT * FROM Departamento NATURAL LEFT JOIN Funcionario; 20/40
Condições de junção: RIGHT JOIN Retorna todas as tuplas da relação à direita, mesmo aquelas que não possuam correspondentes na tabela à esquerda SELECT colunas FROM tabela1 RIGHT JOIN tabela2 ON tabela.colunaa = tabela.colunab; -- Exemplo SELECT * FROM Departamento d RIGHT JOIN Funcionario f ON d.iddepartamento = f.iddepartamento; SELECT * FROM Departamento NATURAL RIGHT OUTER JOIN Funcionario; 21/40
Condições de junção: FULL OUTER JOIN Retorna todas as tuplas de ambas tabelas, mesmo se não houver correspondência de valores SELECT colunas FROM tabela1 FULL OUTER JOIN tabela2 ON tabela.colunaa = tabela.colunab; -- Exemplo SELECT * FROM Departamento d NATURAL FULL OUTER JOIN Funcionario f; MySQL não implementa FULL JOIN 22/40
Exercícios 23/40
Relações do lab02: Funcionário e Departamento 1 Liste todos os dados de todos os funcionários, inclusive todos os dados de seus departamentos 2 Liste o nome do funcionário e o nome do departamento onde cada funcionário está lotado 3 Liste o nome e sobrenome de todos os funcionários que estejam lotados em departamentos com orçamento maior que 60.000, 00 4 Liste os nomes de todos os departamentos que possuam mais de dois funcionários 23/40
Relações do lab02: Funcionário e Departamento 1 Liste todos os dados de todos os funcionários, inclusive todos os dados de seus departamentos SELECT F.*, D.* FROM Funcionario F INNER JOIN Departamento D ON F.idDepartamento = D.idDepartamento; 2 Liste o nome do funcionário e o nome do departamento onde cada funcionário está lotado 3 Liste o nome e sobrenome de todos os funcionários que estejam lotados em departamentos com orçamento maior que 60.000, 00 4 Liste os nomes de todos os departamentos que possuam mais de dois funcionários 23/40
Relações do lab02: Funcionário e Departamento 1 Liste todos os dados de todos os funcionários, inclusive todos os dados de seus departamentos 2 Liste o nome do funcionário e o nome do departamento onde cada funcionário está lotado SELECT F.Nome, D.dNome FROM Funcionario F INNER JOIN Departamento D ON F.idDepartamento = D.idDepartamento; 3 Liste o nome e sobrenome de todos os funcionários que estejam lotados em departamentos com orçamento maior que 60.000, 00 4 Liste os nomes de todos os departamentos que possuam mais de dois funcionários 23/40
Relações do lab02: Funcionário e Departamento 1 Liste todos os dados de todos os funcionários, inclusive todos os dados de seus departamentos 2 Liste o nome do funcionário e o nome do departamento onde cada funcionário está lotado 3 Liste o nome e sobrenome de todos os funcionários que estejam lotados em departamentos com orçamento maior que 60.000, 00 SELECT F.Nome, F.Sobrenome FROM Funcionario F INNER JOIN Departamento D ON F.idDepartamento = D.idDepartamento WHERE D.Orcamento > 60000; 4 Liste os nomes de todos os departamentos que possuam mais de dois funcionários 23/40
Relações do lab02: Funcionário e Departamento 1 Liste todos os dados de todos os funcionários, inclusive todos os dados de seus departamentos 2 Liste o nome do funcionário e o nome do departamento onde cada funcionário está lotado 3 Liste o nome e sobrenome de todos os funcionários que estejam lotados em departamentos com orçamento maior que 60.000, 00 4 Liste os nomes de todos os departamentos que possuam mais de dois funcionários SELECT D.dNome FROM Funcionario F INNER JOIN Departamento D ON D.idDepartamento = F.idDepartamento GROUP BY D.dNome HAVING COUNT(*) > 2; 23/40
Subconsultas aninhadas 24/40
Subconsultas aninhadas Trata-se de de uma consulta aninhada a uma instrução SELECT, INSERT, UPDATE ou DELETE A tupla resultante é então usada pela instrução onde essa está aninhada Geralmente é usada em operações com conjuntos Para verificar se uma tupla pertence ao conjunto, para comparar conjuntos e verificar a cardinalidade de conjuntos 24/40
Subconsultas aninhadas Trata-se de de uma consulta aninhada a uma instrução SELECT, INSERT, UPDATE ou DELETE A tupla resultante é então usada pela instrução onde essa está aninhada Geralmente é usada em operações com conjuntos Para verificar se uma tupla pertence ao conjunto, para comparar conjuntos e verificar a cardinalidade de conjuntos Listar o nome e orçamento do departamento que possui o maior orçamento SELECT Nome, Orcamento FROM Departamento WHERE Orcamento = (SELECT MAX(Orcamento) FROM Departamento); 24/40
Subconsultas aninhadas Aluno(idAluno, nome, codigocurso) Curso(idCurso, cnome) Na tabela Aluno, atualizar todas tuplas com valor = 2 no atributo codigocurso para o código que está associado ao curso chamado Engenharia de Telecomunicações na tabela Curso UPDATE Aluno SET codigocurso = (SELECT idcurso FROM Curso WHERE cnome = 'Engenharia de Telecomunicaç~oes') WHERE codigocurso = 2; 25/40
Subconsultas Diferentes consultas SQL podem apresentar o mesmo resultado Liste o nome de todos os funcionários de todos os departamentos que possuam orçamento maior que 5.000 Fazendo uso de INNER JOIN Fazendo uso de subconsultas (operador IN) 26/40
Subconsultas Diferentes consultas SQL podem apresentar o mesmo resultado Liste o nome de todos os funcionários de todos os departamentos que possuam orçamento maior que 5.000 Fazendo uso de INNER JOIN SELECT f.nome FROM Funcionario f INNER JOIN Departamento d ON f.iddepartamento = d.departamento WHERE d.orcamento > 5000; Fazendo uso de subconsultas (operador IN) 26/40
Subconsultas Diferentes consultas SQL podem apresentar o mesmo resultado Liste o nome de todos os funcionários de todos os departamentos que possuam orçamento maior que 5.000 Fazendo uso de INNER JOIN SELECT f.nome FROM Funcionario f INNER JOIN Departamento d ON f.iddepartamento = d.departamento WHERE d.orcamento > 5000; Fazendo uso de subconsultas (operador IN) SELECT Nome FROM Funcionario WHERE iddepartamento IN (SELECT iddepartamento FROM Departamento WHERE Orcamento > 5000); 26/40
Esquema usado nos próximos exemplos 27/40
Subconsultas Exemplos com operador IN Listar o ID de todos os clientes que possuam uma conta e um empréstimo Listar o ID de todos os clientes que possuam um empréstimo, mas que não possuam uma conta 28/40
Subconsultas Exemplos com operador IN Listar o ID de todos os clientes que possuam uma conta e um empréstimo SELECT DISTINCT idpessoa FROM Mutuario WHERE idpessoa IN (SELECT idpessoa FROM Correntista) Listar o ID de todos os clientes que possuam um empréstimo, mas que não possuam uma conta 28/40
Subconsultas Exemplos com operador IN Listar o ID de todos os clientes que possuam uma conta e um empréstimo SELECT DISTINCT idpessoa FROM Mutuario WHERE idpessoa IN (SELECT idpessoa FROM Correntista) Listar o ID de todos os clientes que possuam um empréstimo, mas que não possuam uma conta SELECT DISTINCT idpessoa FROM Mutuario WHERE idpessoa NOT IN (SELECT idpessoa FROM Correntista) 28/40
Subconsultas Exercícios com operador IN Liste o CPF dos presidentes das empresas que fabricam produtos nos estados de SP e SC Produto(idProduto, idempresa, uffabrica) Empresa(idEmpresa, cpfpresidente) 29/40
Subconsultas Exercícios com operador IN Liste o CPF dos presidentes das empresas que fabricam produtos nos estados de SP e SC Produto(idProduto, idempresa, uffabrica) Empresa(idEmpresa, cpfpresidente) SELECT DISTINCT cpfpresidente FROM Empresa e, Produto p WHERE e.idempresa = p.idempresa AND e.idempresa IN (SELECT idempresa FROM Produto WHERE UFFabrica = 'SP') AND e.idempresa IN (SELECT idempresa FROM Produto WHERE UFFabrica = 'SC') 29/40
Subconsultas Exercícios com operador IN Liste o nome de todas as disciplinas ministradas no segundo semestre de 2014 e no primeiro semestre de 2017 Disciplina(nome, ano, semestre) 30/40
Subconsultas Exercícios com operador IN Liste o nome de todas as disciplinas ministradas no segundo semestre de 2014 e no primeiro semestre de 2017 Disciplina(nome, ano, semestre) SELECT DISTINCT nome FROM Disciplina WHERE semestre = 2 AND ano = 2014 AND nome IN (SELECT nome FROM Disciplina WHERE semestre = 1 AND ano = 2017) 30/40
Subconsultas Exemplo com cláusula FROM Soma dos valores médios de empréstimos realizados por cada agência 31/40
Subconsultas Exemplo com cláusula FROM Soma dos valores médios de empréstimos realizados por cada agência -- Obtendo o valor médio agrupado por ag^encia SELECT AVG(valor) AS valormedio FROM Emprestimo GROUP BY idagencia; +------------+ avg(valor) +------------+ 750 1000 3000 +------------+ 31/40
Subconsultas Exemplo com cláusula FROM Soma dos valores médios de empréstimos realizados por cada agência -- Obtendo o valor médio agrupado por ag^encia SELECT AVG(valor) AS valormedio FROM Emprestimo GROUP BY idagencia; +------------+ avg(valor) +------------+ 750 1000 3000 +------------+ SELECT SUM(AVG(valor)) AS valormedio FROM Emprestimo GROUP BY idagencia; -- instruç~ao inválida! 31/40
Subconsultas Exemplo com cláusula FROM Soma dos valores médios de empréstimos realizados por cada agência -- Obtendo o valor médio agrupado por ag^encia SELECT AVG(valor) AS valormedio FROM Emprestimo GROUP BY idagencia; +------------+ avg(valor) +------------+ 750 1000 3000 +------------+ SELECT SUM(AVG(valor)) AS valormedio FROM Emprestimo GROUP BY idagencia; -- instruç~ao inválida! SELECT SUM(valorMedio) FROM (SELECT AVG(valor) AS valormedio FROM Emprestimo GROUP BY idagencia) AS Resultado; 31/40
Subconsultas Operações com conjuntos Pelo menos um (SOME) > some, < some, >= some, <= some, = some, <> some Que todos (ALL) > all, < all, >= all, <= all, = all, <> all 32/40
Subconsultas Operações com conjuntos Pelo menos um (SOME) > some, < some, >= some, <= some, = some, <> some Que todos (ALL) > all, < all, >= all, <= all, = all, <> all Listar nome, cargo e salário dos funcionários cujo salário seja maior que o salário de pelo menos um Analista Funcionario(idFuncionario, nome, cargo, salario) -- SELECT nome, cargo, salário FROM Funcionario WHERE salario > SOME (SELECT salario FROM Funcionario WHERE cargo = 'Analista'); 32/40
Subconsultas Operações com conjuntos Pelo menos um (SOME) > some, < some, >= some, <= some, = some, <> some Que todos (ALL) > all, < all, >= all, <= all, = all, <> all Listar nome, cargo e salário dos funcionários cujo salário seja maior do que o salário de todos os Analistas Funcionario(idFuncionario, nome, cargo, salario) -- SELECT nome, cargo, salário FROM Funcionario WHERE salario > ALL (SELECT salario FROM Funcionario WHERE cargo = 'Analista'); 32/40
Subconsultas Operações com conjuntos: cláusula SOME 1 5 8 1 5 1 5 1 5 (5 < SOME) = 5 < que alguma tupla na relação? TRUE! (5 < SOME) = FALSE! (5 = SOME) = TRUE! (5 <> SOME) = TRUE!, pois 1 5 33/40
Subconsultas Operações com conjuntos: cláusula SOME 1 5 8 1 5 1 5 1 5 (5 < SOME) = 5 < que alguma tupla na relação? TRUE! (5 < SOME) = FALSE! (5 = SOME) = TRUE! (5 <> SOME) = TRUE!, pois 1 5 (= SOME) IN (<> SOME) NOT IN 33/40
Subconsultas Operações com conjuntos: cláusula ALL 1 5 8 1 6 1 5 1 6 (5 < ALL) = FALSE! (5 < ALL) = TRUE! (5 = ALL) = FALSE! (5 <> ALL) = TRUE! 34/40
Subconsultas Operações com conjuntos: cláusula ALL 1 5 8 1 6 1 5 1 6 (5 < ALL) = FALSE! (5 < ALL) = TRUE! (5 = ALL) = FALSE! (5 <> ALL) = TRUE! (<> ALL) NOT IN (= ALL) IN 34/40
Subconsultas Teste de relação vazia EXISTS Retorna TRUE se a relação resultante da subconsulta for, FALSE caso contrário 35/40
Subconsultas Teste de relação vazia EXISTS Retorna TRUE se a relação resultante da subconsulta for, FALSE caso contrário Liste o nome de todos as disciplinas ministradas no segundo semestre de 2014 e no primeiro semestre de 2017 Disciplina(nome, ano, semestre) SELECT DISTINCT nome FROM Disciplina WHERE semestre = 2 AND ano = 2014 AND EXISTS (SELECT nome FROM Disciplina WHERE semestre = 1 AND ano = 2017) 35/40
Subconsultas Alternativa para INTERSECT e EXCEPT Listar o ID de todos os clientes que são correntistas e que possuam um empréstimo (SELECT idpessoa FROM Correntista) INTERSECT (SELECT idpessoa FROM Mutuario) SELECT idpessoa FROM Correntista c WHERE EXISTS (SELECT idpessoa FROM Mutuario m WHERE c.idpessoa = m.idpessoa); Listar o ID de todos os clientes que são correntistas e que não possuam um empréstimo (SELECT idpessoa FROM Correntista) EXCEPT (SELECT idpessoa FROM Mutuario) SELECT idpessoa FROM Correntista c WHERE NOT EXISTS (SELECT idpessoa FROM Mutuario m WHERE c.idpessoa = m.idpessoa); 36/40
Subconsulta escalar vs GROUP BY Subconsulta escalar retorna uma única tupla com um único atributo Liste o total em R$ das vendas de cada produto Vendas(Produto, qtde, preco) SELECT A.Produto, (SELECT SUM(B.qtde * B.preco) FROM Vendas B WHERE A.Produto = B.Produto) AS TotalVendas FROM Vendas A Mesma consulta, porém fazendo uso de GROUP BY SELECT Produto, SUM(qtde * preco) AS TotalVendas FROM Vendas GROUP BY Produto 37/40
Exemplos com DELETE e múltiplas relações 38/40
Apagando linhas de uma ou mais tabelas Aluno(idAluno, nome, curso) curso referencia Curso Disciplina(idDisc, nome, curso) curso referencia Curso Curso(idCurso, nome) Apagando todas as linhas da tabela Curso cujo código do curso seja igual a 123 DELETE FROM Curso WHERE curso = 123; Apagando todas as linhas das tabelas Curso, Disciplina e Aluno cujo código do curso seja igual a 123 DELETE Curso, Disciplina, Aluno FROM Curso INNER JOIN Disciplina INNER JOIN Aluno WHERE Curso.idCurso = 123 AND Curso.idCurso = Disciplina.curso AND Curso.idCurso = Aluno.curso; 38/40
Exemplos com INNER JOIN e subconsulta Aluno(idAluno, nome, curso) curso referencia Curso Curso(idCurso, nome) Exemplo com INNER JOIN DELETE Aluno FROM Aluno INNER JOIN Curso ON Aluno.curso = Curso.idCurso WHERE Curso.Nome = 'Curso XYZ'; Exemplo com subconsulta DELETE Aluno FROM Aluno WHERE Aluno.curso IN (SELECT idcurso FROM Curso WHERE Curso.Nome = 'Curso XYZ'); 39/40
Aulas baseadas em Henry F.; Sudarshan Silberschatz, Abraham; Korth. Sistemas de banco de dados. 6a. Edição - Editora Campus, 2012 Sullivan, D. G. Computer Science Harvard University 40/40