Tutorial SQL
Aprenda a usar a linguagem SQL para execução de consultas e subconsultas.
Seu guia prático para execução de consultas
Neste artigo você terá a oportunidade de aprender a usar a linguagem SQL para execução de consultas e subconsultas. Serão apresentados os conceitos necessários para a realização de consultas através de um encadeamento especialmente preparado para tornar interessante o seu aprendizado.
Os Sistemas Gerenciadores de Bancos de Dados Relacionais (SGBDr) são o principal mecanismo de suporte ao armazenamento de dados e recuperação de informações utilizadas em diversas aplicações. Em um SGBD, os dados do banco de dados são mantidos em tabelas, o que torna imprescindível o conhecimento dessa estrutura.
Relacionado: Guia Completa de MVC
Anatomia de uma tabela
A tabela é uma estrutura matricial composta por linhas e colunas. Na prática, cada linha representa um objeto do negócio e cada coluna representa uma característica dele. Por exemplo, a Tabela 1 (CLIENTE) representa um cadastro de clientes. Cada cliente possui código, nome, sexo, CPF, data de nascimento e salário.
#CODIGO | NOME | SEXO | CPF | NASCIMENTO | SALARIO |
---|---|---|---|---|---|
1 | Alcides | Masculino | 111222333-44 | 1/12/1975 | R$ 7.000,00 |
2 | Cristiano | Masculino | 222333444-55 | 12/3/1970 | R$ 7.000,00 |
3 | Cristiane | Feminino | 333444555-66 | 20/7/1977 | R$ 1.500,00 |
4 | Marcos | Masculino | 1111234333-44 | 19/8/1989 | R$ 3.500,00 |
5 | Joice | Feminino | 222444555-66 | 20/7/2001 | R$ 2.500,00 |
As linhas de uma tabela são conhecidas por registros ou tuplas. Já as colunas, por campos ou atributos. No desenho, a primeira linha representa os nomes das colunas.
Na prática, a construção de um banco de dados envolve a criação de diversas tabelas relacionadas. O relacionamento entre tabelas ocorre através do uso de um mecanismo denominado chave estrangeira. Para maiores detalhes sobre relacionamentos entre tabelas.
Saiba mais: Seja um mestre SQL
Entendendo relacionamentos entre tabelas
Relacionamentos entre tabelas ajudam a manter íntegros os dados do banco de dados. Para aprender sobre o mecanismo de relacionamento, é interessante estudar as definições de chave primária e de chave estrangeira:
- A chave primária serve para identificar de forma única cada linha de uma tabela. Para isso, é utilizada uma coluna ou uma combinação de colunas da própria tabela. Quando uma chave primária é escolhida, o próprio SGBD se encarrega de realizar as verificações necessárias para manter a integridade dos dados (a chave primária não pode conter valor nulo). Por exemplo, no modelo composto pelas Tabelas 1 e 2, a chave primária da tabela CLIENTE é o campo Código e a da tabela FONE é representada pelos campos Código, Fone e Tipo.
- A chave estrangeira serve para realizar ligações entre tabelas. Tais ligações, ou relacionamentos, são essenciais para ajudar a manter íntegros os dados do banco de dados. Por exemplo, na tabela FONE o campo Código representa a chave estrangeira. Na prática, a tabela FONE depende da tabela CLIENTE. Sendo assim, para que determinado telefone seja cadastrado, é necessário que exista um cliente correspondente na tabela CLIENTE. Neste caso, um cliente pode não ter telefone (cliente Pedro) ou pode possuir vários (cliente Alcides, por exemplo).
#CODIGO | #FONE | #TIPO |
---|---|---|
1 | 34569789 | residencial |
1 | 99009988 | celular |
3 | 88223456 | celular |
4 | 23459899 | residencial |
2 | 87789009 | celular |
A vantagem da linguagem SQL reside no fato dela ser declarativa, ou seja, todo o esforço de codificação de nossa parte é resumido na escrita de solicitações que são submetidas ao SGBD, não importando (pelo menos se não pensarmos em otimização de consultas) a forma que o mesmo utilizará para recuperar as informações.
Uma sintaxe para consultas
Estudada a composição de uma tabela e ciente da importância das chaves primária e estrangeira na manutenção da integridade dos dados do banco de dados, é chegada a hora de conhecer os principais comandos utilizados para a realização de consultas. Para isso, observe o código presente na Figura 1, camisa bastante utilizada por diversos leitores desta revista.
Saiba mais: Cursos de Banco de Dados
A Figura 1 representa a sintaxe SQL utilizada pela maioria dos SGBD. Observe o significado de cada comando:
SELECT [DISTINCT | ALL] {*|table.*|[table].field1}
Esta linha serve para apresentar ao usuário as colunas (field) especificadas;
As colunas podem existir em alguma tabela, ou podem ser calculadas através do uso de alguma função especial (AVG, SUM, COUNT, etc);
As linhas resultantes de uma consulta podem apresentar mesmo conteúdo. Utiliza-se DISTINCT para remover linhas repetidas. Para que sejam apresentadas linhas iguais, utiliza-se opção ALL. Na prática, esta opção é utilizada como padrão na maioria dos SGBDs;
table.* indica a recuperação de todas (*) as colunas de determinada tabela da consulta. Para recuperar apenas determinado atributo, substitui-se o * pelo nome da coluna [table].field1.
- FROM table [, ...]
Nesta linha são declaradas as tabelas envolvidas na consulta;
Em consultas envolvendo várias tabelas, é necessário indicar os campos que fazem parte do relacionamento para que o SGBD possa recuperar corretamente as informações.
É interessante notar que o nome de qualquer tabela pode ser virtualmente modificado, principalmente para facilitar a escrita das consultas.
[WHERE criteria]
Aqui são declarados os mecanismos (conjunto de condições e filtros) necessários à obtenção da informação;
É possível compor diversos critérios de filtro, usando-se para esse fim uma combinação de operadores lógicos (AND, OR, NOT), subconsultas, operadores de pesquisa em cadeia de caracteres, funções de data, entre outros;
Em consultas envolvendo várias tabelas, pode-se estabelecer a condição de ligação entre elas.
[GROUP BY groupfieldlist]
Esta opção é utilizada para agrupar informações em uma consulta;
Em groupfieldlist declara-se um conjunto de atributos os quais o SGBD considerará um grupo;
Quando utilizado em conjunto com funções de agregação (por exemplo, AVG e SUM), os resultados dessas funções são calculados para cada grupo declarado em groupfieldlist.
[HAVING groupcriteria]
De maneira semelhante à WHERE, esta opção serve para realizar filtros na consulta;
Os filtros realizados por HAVING são executados após a operação de grupamento ter sido executada. Neste caso, é possível utilizar funções de agregação como critérios de filtro.
[ORDER BY field1 [ASC | DESC]
É utilizada para ordenar o resultado da consulta;
É possível escolher, para cada coluna, o tipo de ordenação (ascendente ou descendente);
A maioria dos SGBD utiliza como padrão a ordenação ascendente, neste caso tornando desnecessária a declaração do critério ASC.
Nesta parte, realizamos uma breve revisão sobre conceitos do mundo relacional de dados, além da apresentação de uma sintaxe SQL para recuperação de informação.
Praticando consultas
Para os exemplos, serão utilizadas as tabelas CLIENTE e FONE, apresentadas na primeira parte do tutorial.
SELECT *
FROM CLIENTE
Comentário: neste caso, o * substitui a declaração de todos os campos da tabela CLIENTE. Outra forma de realizar esta consulta é:
SELECT CLIENTE.*
FROM CLIENTE
É possível também escrever a consulta da seguinte forma, renomeando (virtualmente) a tabela CLIENTE:
SELECT C.*
FROM CLIENTE C
SELECT nome, nascimento
FROM CLIENTE
Aqui, bastou inserir na cláusula SELECT os campos correspondentes à informação pedida. Outra forma de realizar esta consulta é:
SELECT CLIENTE.nome, CLIENTE.nascimento
FROM CLIENTE
Ou mesmo:
SELECT C.nome, C.nascimento
FROM CLIENTE C
SELECT nome, cpf
FROM CLIENTE
WHERE sexo=’masculino’
Neste caso, utilizou-se o filtro sexo=’masculino’ para retornar apenas os indivíduos do sexo masculino.
SELECT nome, cpf
FROM CLIENTE
WHERE sexo=’masculino’
ORDER BY nome DESC
Aproveitou-se a solução anterior adicionando-se apenas a cláusula de ordenação de acordo com a descrição do problema.
SELECT nome, salario
FROM CLIENTE
WHERE sexo=’masculino’ and salario < 3000
Aqui, tornou-se necessário o uso da expressão lógica de conjunção (and), para poder recuperar os clientes do sexo masculino (sexo=’masculino’) que ganham menos de R$ 3000 (salario < 3000). A expressão lógica (and) faz com que o SGBD retorne apenas as linhas que obedecem as duas condições simultaneamente.
Recuperando informações de várias tabelas
Em diversas situações, existe a necessidade da execução de consultas cujos campos estão localizados em tabelas diferentes. Neste caso, além de declarar as tabelas, é necessário indicar que elas estão relacionadas para que o SGBD possa recuperar as informações de forma coerente. Há duas formas de realizar esta tarefa:
- Declarar as tabelas na cláusula FROM, indicando o relacionamento na cláusula WHERE, ou;
- Declarar as tabelas e indicar o tipo de relacionamento na cláusula FROM. Esta abordagem será estudada em outra oportunidade.
Para o Exemplo 06, temos:
SELECT nome, fone
FROM CLIENTE, FONE
WHERE CLIENTE.codigo=FONE.codigo and tipo=’residencial’
Na cláusula FROM, foram declaradas as tabelas que possuem os campos (nome e fone) que devem aparecer no resultado. Na cláusula WHERE, CLIENTE.codigo=FONE.codigo representa o relacionamento entre as tabelas CLIENTE e FONE. Através desse trecho de código o SGBD filtra os registros que correspondem às informações corretas de cada cliente. Já o código tipo=’residencial’ solicita ao SGBD que sejam recuperados apenas os telefones residenciais.
Na realidade, nessas situações o SGBD comumente realiza os seguintes passos:
Execução da operação de produto cartesiano entre as tabelas. Isto significa combinar cada linha da tabela CLIENTE com cada linha da tabela FONE, resultando numa estrutura que possui todas as colunas existentes nas tabelas envolvidas, e quantidade de linhas igual ao produto das linhas de cada tabela (no exemplo, 5 x 5 = 25 linhas). A Figura 1 representa esta situação.
Remoção das linhas que não correspondem à realidade do banco de dados. Observe que as linhas realçadas em cinza representam informações incorretas. Na prática, devem permanecer na tabela apenas as linhas cujos valores do campo código são idênticos (CLIENTE.codigo=FONE.codigo – linhas marcadas da Figura 1), configurando a situação apresentada na Figura 2.
A cláusula tipo=’residencial’ considera apenas os telefones que são do tipo residencial (as linhas marcadas na Figura 2 são descartadas). Neste caso, temos o resultado intermediário apresentado na Figura 3.
Finalmente, são mostrados apenas os campos declarados na cláusula SELECT (ver Figura 4).
SELECT nome, sexo, fone
FROM CLIENTE, FONE
WHERE CLIENTE.codigo=FONE.codigo and tipo=’celular’
Esta solução é semelhante à do exemplo 6, sendo adicionado o campo sexo e modificado o campo tipo (tipo=’celular’) para recuperar apenas os clientes que possuem celular.
Nesta parte, foram apresentados diversos exemplos de consultas utilizando a linguagem SQL. Na última parte desse tutorial, estudaremos exemplos mais complexos, envolvendo funções de agregação e subconsultas.
Funções de agregação e elaboração de subconsultas.
SELECT COUNT(*)
FROM CLIENTE
O comando count serve para contabilizar o número de linhas de uma consulta. No exemplo, count(*) retornou o número de linhas da tabela CLIENTE que, nesse contexto, representa o número de clientes.
SELECT COUNT(*)
FROM CLIENTE
WHERE sexo=’feminino’
Trata-se de uma solução semelhante à do exemplo 1. Apenas foi adicionada a cláusula WHERE com um filtro que recupera as linhas correspondentes às pessoas do sexo feminino (sexo=’feminino’).
SELECT AVG(salario)
FROM CLIENTE
Esta é uma solução simples. Bastou a utilização da função que calcula a média (avg) a partir de um conjunto de valores (neste caso, o campo salário da tabela CLIENTE). Uma alternativa pode ser vista na Nota 1.
É possível renomear virtualmente qualquer coluna resultante de uma consulta. Este procedimento é útil para deixar o código mais organizado e coerente. Dessa forma, é possível reescrever a solução do Exemplo 03 da seguinte maneira:
SELECT AVG(salario) as MediaSalarial
FROM CLIENTE
SELECT sexo, AVG(salario) as MediaSalarialSexo
FROM CLIENTE
GROUP BY sexo
Esta solução é semelhante à do exemplo 10. Aqui, foi adicionado o campo (sexo) na cláusula GROUP BY para que o resultado fosse calculado para o sexo masculino e para o feminino.
SELECT
(SELECT COUNT(*) FROM CLIENTES WHERE sexo=’masculino’) AS QtdeHomens,
(SELECT COUNT(*) FROM CLIENTES WHERE sexo=’feminino’) AS QtdeMulheres
O interessante desta solução é que podemos exibir resultados, dos mais simples aos mais complexos, em uma única linha. Para isso, basta declarar um SELECT principal separando, em seguida, por vírgula, cada subconsulta que gera determinada informação.
Praticando subconsultas
No dia-a-dia, os desenvolvedores codificam consultas que não dependem diretamente de alguma tabela, mas do resultado de uma ou de diversas consultas. Este procedimento é comumente chamado de subconsulta. Na prática, o SGBD realiza a subconsulta e o resultado serve como parâmetro de entrada para a consulta principal. Observe os exemplos de 06 a 07.
Note que para sabermos o nome dos clientes sem telefone, é necessário termos certeza de que não existe ocorrência do código do cliente na tabela FONE. Em situações desse tipo, pode-se utilizar o operador (not) in. Observe:
SELECT nome
FROM CLIENTE
WHERE codigo not in
(SELECT codigo
FROM FONE)
Neste caso, o SGBD primeiramente recupera os códigos dos clientes da tabela FONE (SELECT código FROM FONE). Este resultado serve como parâmetro de entrada para a consulta principal, que recupera apenas os clientes sem telefone (clientes cujo código não aparece na subconsulta).
SELECT nome, salario
FROM CLIENTE
WHERE salario >
(SELECT avg(salario)
FROM CLIENTE
WHERE SEXO=’MASCULINO’)
Aqui, o SGBD primeiramente calcula a média salarial dos clientes do sexo masculino (subconsulta). O resultado é comparado com o salário de cada cliente, sendo retornadas apenas as informações dos que ganham mais que a média salarial masculina.
SELECT nome
FROM CLIENTE
WHERE salario =
(SELECT max(salario)
FROM CLIENTE)
Neste caso, o SGBD calcula o maior salário através da utilização do operador max na subconsulta (SELECT max(salário) from CLIENTE). Este resultado é comparado com o salário de cada cliente, sendo exibidos apenas os que ganham o correspondente ao maior salário.
SELECT count(*) as QteCliente
FROM CLIENTE
WHERE salario >
(SELECT min(salario)
FROM CLIENTE)
Aqui, a subconsulta recupera o menor salário da tabela CLIENTE. Este salário serve como parâmetro de comparação para a consulta principal, que contabiliza o número de clientes que ganham mais que este salário.
SELECT nome, sexo
FROM CLIENTE
WHERE nascimento =
(SELECT max(nascimento)
FROM CLIENTE)
Observe que neste caso a subconsulta recupera a maior (mais recente) data de nascimento, dentre as cadastradas na tabela CLIENTE. Este resultado serve como parâmetro de entrada para a consulta principal, que retorna o cliente mais novo (podendo ser mais de um cliente).
SELECT nome, sexo
FROM CLIENTE
WHERE nascimento =
(SELECT min(nascimento)
FROM CLIENTE)
De forma semelhante ao exemplo 10, a subconsulta recupera a data de nascimento mais antiga. Neste caso, o cliente que tiver nascido nesta data, é o que aparecerá no resultado (podendo ser mais de um cliente).
Conclusões
Estudamos neste tutorial os componentes da estrutura utilizada pelos SGBD para o armazenamento dos dados (tabela). Aprendemos que as tabelas são relacionadas através do mecanismo conhecido por chave estrangeira. Vimos também uma sintaxe SQL para consulta aos dados armazenados em um banco de dados, consolidando o aprendizado através de diversos exemplos.
Links Úteis sobre MVC
- O que é MVC?:
MVC é atualmente o padrão arquitetural mais utilizado no desenvolvimento web, portanto seu conhecimento é fundamental para a construção de projetos bem estruturados.
- Spring MVC: Construa aplicações responsivas com Bootstrap:
Desenvolva aplicações responsivas integrando o framework web da Spring com o Bootstrap, uma das bibliotecas de front-end mais conhecidas.
- ASP.NET MVC:
Neste Guia de Referência você encontrará o conteúdo que precisa para aprender a desenvolver aplicações web com o framework ASP.NET MVC e a linguagem C#.
Saiba mais sobre MVC ;)
- JSF - JavaServer Faces:
Neste Guia de Referência você encontrará todo o conteúdo que precisa para conhecer o JSF, especificação Java que traz conceitos do padrão MVC e que facilita a construção de interfaces web utilizando componentes.
- CRUD em PHP e MVC com Busca e Paginação:
Aprenda a implementar uma busca, paginação e conversão monetária em PHP e MVC.
- Como implementar o MVC em PHP:
O padrão MVC é amplamente utilizado no desenvolvimento de aplicações web, e saber implementá-lo é importante para trabalhar de forma eficiente com frameworks como CodeIgniter e Laravel, bem como para desenvolver projetos sem depender dessas soluções de terceiros.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo