Escolar Documentos
Profissional Documentos
Cultura Documentos
27/06/2022
Objetivo(s):
Caro(a) aluno(a), você já deve conhecer o comando SELECT, que é utilizado para recuperar
dados e informações gravados no Banco de Dados, bem como gerar relatórios customizados.
Esse comando é um dos mais poderosos da linguagem SQL (Structured Query Language –
Linguagem Estruturada de Consulta).
Além disso, sabia que, com o comando SELECT, é possível recuperar informações de diferentes
conjuntos de dados, combinando os resultados e gerando um novo conjunto/tabela? Você
já ouviu falar em tabelas temporárias e que existem dois tipos delas? Consegue escrever uma
instrução SQL que retorne dados de diferentes tabelas, na quais exista o registro em uma, e não
existe na outra? Ou que existe em duas tabelas, e não existe em uma terceira?
Nesta Aula, praticaremos a escrita de instruções SELECT, utilizando comandos e uma parte
mais avançada da linguagem SQL/T-SQL. Aprenderemos a criar e excluir tabelas temporárias,
fazer JOIN com uma tabela resultante de uma subconsulta, agregar os dados gerados pelas
consultas e filtrá-los depois de agregados. E, por fim, aprenderemos a utilizar o comando PIVOT
e calcular tabelas dinamicamente.
Bons Estudos!
2
MAPA MENTAL PANORÂMICO
Para contextualizar e ajudá-lo(a) a obter uma visão panorâmica dos conteúdos que você
estudará na Aula 1, bem como entender a inter-relação entre eles, é importante que se atente
para o Mapa Mental, apresentado a seguir:
SELECT DO RESULTADO
DE UMA CONSULTA
FAZENDO JOIN
ENTRE TABELAS E
SUBCONSULTAS
TABELAS
TEMPORÁRIAS E
VARIÁVEIS DE TABELAS
PIVOT E UNPIVOT
- CALCULANDO
TABELAS
DINAMICAMENTE
3
PRÁTICAS DE RECUPERAÇÃO AVANÇADA DE DADOS
Como estudado em Álgebra e Cálculo Relacional, bem como no Modelo de Dados Relacional,
todo resultado de uma operação SELECT é um novo conjunto de dados, formado por linhas e
colunas. Portanto, esse novo conjunto de dados também é uma tabela que, por definição, é
um conjunto de linhas e colunas.
Na linguagem SQL, é possível que se utilize do resultado de uma consulta para manipular dados
e obter um novo resultado, podendo renomeá-lo, inseri-lo em outra tabela, ou mesmo fazer um
JOIN desse resultado com outra tabela.
4
Figura 2 - Resultado do SELECT dos funcionários que nasceram em janeiro de 1990
Entretanto, essa nova tabela gerada não consta, fisicamente, no Banco de Dados, pois não
houve nenhuma operação de INSERT que gravou os dados ou SELECT com INTO que gerou
uma nova tabela.
Com este novo conjunto de dados TB_RESULTADO, pode-se inserir os dados em uma tabela física
ou executar uma operação de JOIN com outras tabelas para obter outros resultados, como,
por exemplo, selecionar os dados dos funcionários mais o nome e o CPF (Cadastro de Pessoas
Físicas) dos dependentes destes que possuem dependentes. Se não existir dependentes, o
resultado deverá ser ignorado para esses registros, como mostram as Figuras 3 e 4.
5
O resultado dessa consulta é apresentado na Figura 4.
Neste caso, apenas um registro desse conjunto de dados de funcionário possui, pelo menos,
um dependente vinculado.
VAMOS PRATICAR?!
Exercício 1
Além de poder escrever instruções SELECTs, consultando dados de uma tabela ou uma
subconsulta, você pode fazer JOIN entre esses diversos conjuntos de dados para gerar um novo
conjunto, fazendo com que seja criado um resultado preciso com uma consulta avançada e
que atenda às suas necessidades ou às dos seus clientes (caso você tenha).
É possível fazer JOIN entre tabelas do Banco de Dados, tabelas e subconsultas, bem como
entre mais de uma subconsulta, pois cada um desses conjuntos de registros forma uma nova
tabela, já que seu resultado é um conjunto de linhas e colunas.
O exemplo da Figura 5 mostra como utilizar JOIN entre tabelas do Banco de Dados formando
um conjunto para uma subconsulta na qual serão realizados JOINs com outras subconsultas.
6
Figura 5 - Instrução SELECT - JOIN entre tabelas e subconsultas
7
## como prefixo, podendo ser visualizadas por todas as conexões da mesma instância. Ambas
as tabelas temporárias são eliminadas logo que a sessão que as criou é finalizada (HOTEK,
2010a).
Variáveis de tabelas são criadas como uma variável comum, utilizando o DECLARE, porém
com uma estrutura de tabela. Elas são visíveis apenas na conexão que as declarou e podem
ser utilizadas para informar conjuntos de dados como parâmetros dentro de procedimentos
armazenados ou funções. São geradas na memória e perdem a alocação logo após o término
da execução da instrução que as declarou, ou seja, elas são criadas quando se executa uma
instrução e, assim que essa instrução finaliza, a tabela é apagada em seguida (HOTEK, 2010b).
! FIQUE ATENTO!
Uma das diferenças básicas entre tabelas temporárias e variáveis de tabelas
é que aquelas são criadas e armazenadas em disco (tempdb), já estas são
gerenciadas em memória o que, em determinados casos, possui melhor
desempenho.
8
VAMOS PRATICAR?!
Exercício 2
Os operadores de JOIN são muito utilizados quando precisamos realizar consultas que envolvem
e relacionam mais de uma tabela, ou mesmo relacionar uma tabela com ela mesma. O
operador INNER JOIN foi introduzido no padrão SQL pelo ANSI (American National Standards
Institute), instituição americana de padronizações, que especifica, na cláusula FROM, a forma
como as tabelas fazem a junção. O INNER JOIN é utilizado em diversas consultas para retornar
os dados que constam em uma tabela que possui equivalência com dados de outra tabela,
através dos critérios utilizados na cláusula ON, por exemplo, consultar todos os funcionários
que possuem dependentes. Daí é preciso que exista o registro do funcionário na tabela de
funcionários e deve possuir um dependente vinculado a este na tabela de dependentes
(FURMANKIEWICZ, 2007a).
Esse operador elimina todas as linhas de ambas as tabelas que não atendem aos critérios.
Porém, nem sempre o relacionamento entre os dados de diferentes tabelas é obrigatório, pois
pode ser que um determinado registro não dependa de um relacionamento com outra tabela,
por exemplo, em um relacionamento entre as tabelas fornecedor e produto, pode ser que
tenha fornecedor cadastrado que não venda um determinado produto, como pode haver um
produto que não seja vendido por nenhum fornecedor, pois pode ser de fabricação própria.
Para esses casos, temos que utilizar outros operadores de JOIN para fazer a junção entre as
9
tabelas, os OUTER JOINS, como o LEFT JOIN, RIGHT JOIN ou o FULL JOIN. O uso do [OUTER], nesses
operadores, é uma questão do padrão ANSI, porém, no SQL Server, seu uso é opcional.
A instrução SELECT que retorna esse resultado, utilizando o operador LEFT JOIN, é apresentada
na Figura 7.
10
Se você executar essa consulta no SQL Server da sua máquina, verá que o total de registros da
consulta é exatamente igual ao total de funcionários cadastrados na tabela.
Dessa forma, o operador LEFT JOIN considera a tabela da esquerda para procurar os registros
correspondentes na tabela da direita, os que possuírem relação terão seus dados retornados,
já os que não possuírem correspondência na tabela da direita serão retornados como NULL,
conforme mostram alguns dos registros da Figura 8.
Caso você queira retornar apenas os registros de funcionários que possuem dependentes e
eliminar os registros que estão como NULL na tabela da direita, basta informar, na cláusula
WHERE, um campo chave da tabela da direita, onde for IS NOT NULL, como mostra a Figura 9.
Figura 9 - LEFT JOIN utilizando WHERE com coluna chave IS NOT NULL na tabela da direita
Execute a consulta apresentada na Figura 9 no SQL Server da sua máquina e perceba que, no
resultado retornado, não há nenhum registro com os dados de dependente como NULL.
Entretanto, caso você queira recuperar apenas os registros dos funcionários que não possuem
dependentes vinculados, ao invés de utilizar o IS NOT NULL na cláusula WHERE, deverá utilizar o
IS NULL, como mostra a Figura 10.
11
Figura 10 - LEFT JOIN utilizando WHERE com coluna chave IS NULL na tabela da direita
Execute a consulta apresentada na Figura 10 no SQL Server da sua máquina e perceba que, no
resultado retornado, todos os registros estão com NULL nos dados referentes ao dependente.
O operador RIGHT JOIN possui uma lógica bem semelhante ao LEFT JOIN, porém o resultado
é o inverso, pois, em vez de levar em consideração a tabela da esquerda para procurar os
registros correspondentes, ou não, na tabela da direita, ele usa a tabela da direita como base
e pesquisa os registros na tabela da esquerda.
12
Figura 11 - Exemplo de consulta utilizando o RIGHT JOIN
Observe que a consulta apresentada na Figura 11 retornou 10.001 registros como resultado,
sendo que 10.000 deles têm vínculo dos departamentos com a tabela de funcionários, e apenas
1 departamento não possui nenhum funcionário vinculado, trazendo os dados da tabela da
direita (DEPARTAMENTO) e os dados da tabela da esquerda (FUNCIONARIO) como NULL.
O operador OUTER JOIN é utilizado para combinar dados entre duas tabelas, porém ele preserva
todos os registros de um dos lados do JOIN, como é o caso do LEFT e do RIGHT JOIN. Por padrão,
esses dois operadores de JOIN, o LEFT e o RIGHT, já utilizam o OUTER implícito, preservando as
linhas de uma tabela e anexando as linhas correspondentes na outra tabela. A diferença está
em utilizar, ou não, um campo chave da outra tabela na cláusula WHERE como “IS NULL” ou “IS
NOT NULL” para alterar o resultado, como visto anteriormente.
13
Já o operador FULL OUTER JOIN retornará os registros de ambas as tabelas, preservando o
conteúdo da tabela à direita e à esquerda e trazendo o conteúdo correspondente em seguida.
Onde não houver nenhuma correspondência, será retornado NULL no conjunto resultante da
consulta, tanto nas linhas da tabela da esquerda quanto nas da direita.
Por exemplo, para consultar os registros de projetos e dos departamentos onde os locais
possuem correspondência, mas trazer, no resultado, também todos os registros de ambas as
tabelas, mesmo que não exista igualdade na comparação, a consulta ficará semelhante a da
Figura 12.
Execute essa consulta (Figura 12) no SQL Server da sua máquina e observe que, no resultado da
Figura 12, foram retornados 55 registros. As três primeiras colunas do resultado referem-se à tabela
PROJETO e as três últimas, à tabela DEPARTAMENTO. Note que, quando há correspondência
entre as duas tabelas, ou seja, quando o valor da coluna LOCAL_PROJETO é igual ao valor da
coluna LOCAL_DEPART, todas as colunas desta linha do resultado terão valores. Já as linhas
que não possuem correspondência para esta coluna, ou seja, os valores são diferentes e não
existem na outra tabela, os dados para as colunas desta linha, referentes à outra tabela, serão
NULL.
14
CONECTANDO
Em uma consulta SELECT, agregando dados de forma simples, o resultado será apenas um valor
para toda a tabela. Por exemplo, considere que precise ser retornado o valor total dos salários
dos funcionários do departamento de código 1, então a consulta seria como na Figura 13.
Desta forma, quando precisar retornar apenas um valor agregado, não será necessário utilizar
a cláusula GROUP BY.
15
Mesmo que, em algumas situações, você precise retornar valores em apenas uma linha e
coluna, agregando todos os registros da tabela, muitas das vezes será necessário retornar
outras informações, em conjunto com os valores que foram agregados. Como cita Hotek
(2010b, p. 166): “a cláusula GROUP BY permite que você defina as colunas que são usadas
para computar valores agregados”.
Por exemplo, suponha que você, além de calcular o salário dos funcionários, também precise
saber essa informação separada por departamento, ou seja, consultar o valor total dos salários
dos funcionários de cada departamento. Dessa forma, basta incluir a coluna COD_DEPART no
SELECT, como mostra a Figura 14.
16
Fonte: Elaborada pelo Autor.
Execute essa consulta (Figura 15) no SQL Server da sua máquina, assim, perceberá que o
resultado retornou 20 registros. Então, você pode se perguntar: a tabela de departamento
possui 21 registros cadastrados, sendo assim, não deveria retornar 21 linhas agregadas? A partir
dessa pergunta, surge um importante detalhe: o tipo de JOIN utilizado. Neste caso, foi utilizado
o INNER JOIN, portanto, como existem 21 registros cadastrados na tabela DEPARTAMENTO,
mas, na tabela funcionário, não existe nenhum funcionário vinculado ao departamento de
código 21, então esse registro não é computado no resultado. Utilizando essa mesma consulta
para retornar o registro do departamento de código 21 neste resultado, deverá ser utilizado o
operador RIGHT JOIN, porém, mesmo assim, o valor de salário para este registro será NULL.
SAIBA MAIS!
A cláusula GROUP BY possui algumas opções de operações que podem ser utilizadas
para auxiliar e otimizar o resultado retornado para as agregações, são elas: GROUP
BY ROLLUP; GROUP BY CUBE(); GROUP BY GROUPING SETS; e GROUP BY (). Para saber
como funciona cada uma dessas operações, clique aqui, veja os exemplos e pratique
utilizando cada uma dessas operações.
Após ler o conteúdo proposto, você conseguiu aprender mais sobre o funcionamento
da cláusula GROUP BY? Compreendeu as opções de variações de agregação que
você pode utilizar em conjunto com ela?
Essas outras opções que são utilizadas juntamente com a cláusula GROUP BY funcionam
como uma forma de otimização do resultado do agrupamento, auxiliando na forma de
melhorar a visão dos resultados dos dados recuperados.
17
5.1 FILTRANDO DADOS AGREGADOS
Após você aprender a filtrar linhas em uma consulta SELECT, utilizando a cláusula WHERE, e a
agregar os dados de um resultado, utilizando GROUP BY, quando solicitaram que você filtre um
resultado agregado, a lógica seria aplicar mais um filtro na cláusula WHERE. Pois bem, vamos
ao seguinte exemplo: suponhamos que você precise retornar o código do departamento, da
tabela FUNCIONARIO, o nome do departamento, da tabela DEPARTAMENTO, a soma total dos
salários dos funcionários e a quantidade total de funcionários de cada departamento, apenas
dos funcionários que possuem a data de nascimento maior ou igual a „01/01/2000‟, cujo salário
do departamento seja maior ou igual a R$ 5.000,00. A consulta poderia ser semelhante à da
Figura 16.
18
executa as agregações e os agrupamentos necessários. Portanto, com o filtro do salário na
cláusula WHERE, o SQL Server elimina os registros de funcionários que possuem o salário menor
que R$ 5.000,00 da soma total do departamento e pode ser que, por conta dessa condição,
talvez um departamento que tivesse o salário total maior ou igual a R$ 5.000,00 não seja
retornado justamente por eliminar os registros de funcionários com salário menor que esse valor.
Uma das soluções para essa situação seria retirar a condição restritiva do salário da cláusula
WHERE, inserir o resultado da consulta agrupada em uma tabela (física ou temporária) e,
depois, filtrar os departamentos que possuem salário maior ou igual a R$ 5.000,00. Entretanto, a
linguagem T-SQL possui uma forma mais simples e prática de resolver que é utilizando a cláusula
HAVING. Ela é utilizada para filtrar um resultado após a agregação e o agrupamento das linhas.
A consulta correta é apresentada na Figura 17.
19
VAMOS PRATICAR?!
Exercício 3
A estrutura normal de uma tabela de um Banco de Dados é formada por linhas e colunas,
entretanto, nem sempre essa estrutura atende às necessidades de uma aplicação ou às
expectativas dos clientes. Vez ou outra é preciso alternar os dados das linhas para as colunas,
ou das colunas para as linhas, enquanto se executa uma agregação e/ou agrupamento. Esse
novo conjunto de dados pode dar origem a uma tabela dinâmica, que pode ser calculada e
gerada utilizando as cláusulas PIVOT ou UNPIVOT (HOTEK, 2010b).
20
Suponha que você precise gerar um relatório da quantidade de funcionários separados e
agrupados pelo ano em que nasceram e pelo departamento em que trabalham, apenas para
os funcionários que nasceram nos anos 1940, 1950, 1960, 1970, 1980, 1990, 2000. Dessa forma, o
ideal seria contar a quantidade de funcionários, agrupando pelo departamento e pelo ano do
nascimento, como mostra o script da Figura 19.
Execute esse script no SQL Server da sua máquina e veja o resultado. Perceba que esse
comando SELECT retorna um resultado de 110 linhas, retornando o código do departamento,
somando a quantidade de funcionários que trabalha nele, agrupados por ano de nascimento.
Note que o código do departamento e o ano de nascimento se repetem várias vezes.
Caso queira visualizar esse mesmo resultado, porém de uma forma diferente, transformando os
dados das linhas em colunas e evitando que os dados se repitam, então você pode utilizar o
operador PIVOT para realizar esta ação, como mostra na Figura 20.
21
O resultado dessa consulta é apresentado abaixo, na Figura 21.
Note (Figura 21) que foram agrupadas as quantidades de funcionários por código de
departamento e ano de nascimento, todos em uma única linha, transformando o ano de
nascimento em cabeçalho da coluna e convertendo os valores de quantidade de funcionários
das linhas para as colunas, dessa maneira, melhorando e simplificando a forma de visualização
dos dados. A cláusula IN determina através de quais colunas a agregação será calculada.
A operação UNPIVOT executa uma ação oposta à PIVOT, transformando os dados que estão
agrupados e somados os totais, por linha, em valores de coluna.
22
AUTOAVALIAÇÃO
Após estudar o conteúdo desta Aula, você consegue desenvolver consultas,
em SQL, recuperando dados de múltiplos conjuntos? Você aprendeu como
combinar diversos conjuntos de dados fazendo junção entre tabelas e um
conjunto de dados resultante de uma subconsulta? Aprendeu os conceitos
de tabelas temporárias e como utilizá-las? Você entendeu os conceitos de
INNER JOIN e dos OUTER JOINS a ponto de criar códigos que recuperem dados
de mais de uma tabela, que existem em ambas as tabelas ou existe em uma
e não existe na outra? Você aprendeu o funcionamento da cláusula GROUP
BY para agregar dados, quando utilizá-la e como aproveitar os benefícios
de filtrar dados agregados utilizando a cláusula HAVING? Aprendeu como
utilizar as CTE‟s (Expressões Comuns de Tabelas) e como calcular tabelas
dinâmicas? Caso tenha conseguido responder à todas estas perguntas,
parabéns! Você atingiu os objetivos desta Aula!
RECAPITULANDO
Nessa Aula, você conheceu um pouco mais sobre o comando SELECT e aprendeu a extrair um
pouco mais do que essa poderosa instrução tem para nos oferecer no quesito recuperação de
dados dos Banco de Dados. Esse comando, juntamente com diversos operadores e cláusulas
que nos dão suporte, permite escrever consultas avançadas das quais precisaremos para as
nossas aplicações e sistemas.
Vimos sobre como e quando utilizar consultas que envolvem mais de uma tabela, sejam elas
realizadas com junções entre subconsultas ou entre duas tabelas, a fim de recuperarmos
dados dos quais necessitamos ou que outras pessoas necessitam para obterem informações
relevantes. Aprendemos que essas junções podem ser feitas através de vários operadores de
JOIN, onde cada qual tem o seu significado e relevância no momento de analisarmos entre
qual deles escolher para atender às nossas necessidades.
23
fim de melhorarmos e aperfeiçoarmos os resultados das nossas consultas, bem como a calcular
tabelas dinâmicas utilizando os comandos PIVOT e UNPIVOT.
Instruções de consultas do tipo SELECT não são utilizadas apenas para gerar relatórios e
recuperar dados e informações, são utilizadas também em procedimentos e tarefas que
precisamos executar no Banco de Dados, sempre que necessário. Esses procedimentos e
tarefas podem aproveitar os benefícios oferecidos pelos resultados do comando SELECT para
que sejam executadas operações e rotinas essenciais para os sistemas e as aplicações, bem
como para o gerenciamento dos dados e do Banco de Dados.
24
FOLHA DE RESPOSTAS
Exercício 1:
25
Exercício 2:
26
Exercício 3
27
REFERÊNCIAS
FURMANKIEWICZ, E. Microsoft SQL Server 2005: fundamentos de bancos de dados passo a
passo. Solid Quality Learning. Porto Alegre: Bookman, 2007a.
FURMANKIEWICZ, E. Microsoft SQL Server 2005: técnicas aplicadas passo a passo. Solid Quality
Learning. Porto Alegre: Bookman, 2007b.
HOTEK, M.. Kit de Treinamento MCTS (Exame 70-432): Microsoft SQL Server 2008: implementação
e manutenção. Porto Alegre: Bookman, 2010a.
HOTEK, M.. Microsoft SQL Server 2008: passo a passo. Porto Alegre: Bookman, 2010b.
LEBLANC, P.. Microsoft SQL Server 2012: passo a passo. Porto Alegre: Bookman, 2014.
MANZANO, J. A. N. G.. Microsoft SQL Server 2016: express edition interativo. São Paulo: Érika,
2017.
MICROSOFT. Quais são as funções do banco de dados SQL? 2017. Disponível em: <https://docs.
microsoft.com/pt-br/sql/t-sql/functions/functions?view=sql-server-2017>. Acesso em: 08 jul. de
2020.
OTEY, M.; OTEY, D.. Microsoft SQL Server 2005: Guia do Desenvolvedor. Rio de Janeiro: Editora
Ciência Moderna, 2007.
STANEK, W. R.. Microsoft SQL Server 2008: guia de bolso do administrador. Porto Alegre: Bookman,
2010.