Atenção: esse artigo tem um vídeo complementar. Clique e assista!
O artigo aborda o tema subconsultas na linguagem SQL, apresentando um estudo de caso e exemplos de subconsultas aplicados a ele.
Para que serve:
A aplicação de subconsultas proporciona maior simplicidade e, em certos casos, melhoria de desempenho no retorno de consultas em SQL, o que impacta diretamente no desempenho da aplicação.
Em que situação o tema é útil:
Sistemas de informação, em geral, são baseados em banco de dados que armazenam as informações referentes à aplicação em questão. Consultas (queries) são sempre necessárias com o propósito de manipular tais dados, e a aplicação de subconsultas é útil sempre que necessário fazer análise (filtro) de dados a partir de resultados de consultas anteriores.
O banco de dados tem se tornado vitalício tanto para as aplicações web quanto para as aplicações para desktop, e é por esse motivo que cada vez mais tem se deixado o trabalho pesado para o SGBD, fazendo com que o banco de dados faça o papel do “estômago” de um sistema. Neste caso então, a interface recebe a informação já tratada, pronta para o uso. Para que isso aconteça, se faz necessário o uso das subconsultas para complementar o papel do banco de dados.
O objetivo do banco de dados é enviar para a interface a informação tratada. Com isso, o banco envia somente os dados que devem ser exibidos, e finalmente sobra para a interface somente o papel de mostrar de maneira “amigável” o resultado proporcionado pelo banco de dados.
A complexidade das subconsultas gera todo um questionamento envolvendo as mesmas. Por isso elas têm se tornado uma grande incógnita para aqueles que a utilizam, desde estudantes da área até programadores experientes. Baseando-se neste fato, essa é a razão de abordar esse assunto neste artigo para esclarecer e desmistificar o seu uso.
Uma subconsulta é uma consulta aninhada. Sendo assim, é realizada uma pesquisa com base no resultado da outra. Então, para ser uma subconsulta teremos que ter pelo menos dois select’s encadeados. Um que a partir de comparações trará os resultados e o outro que os usará como parâmetro para confrontar os dados e ver quem será exibido ao final da execução.
As subconsultas, chamadas também de Subquery ou Subselect, quando empregadas com bom senso acabam agilizando consideravelmente o trabalho do desenvolvedor. No entanto, um caso muito comum é deixar a função da subconsulta para o front-end (interface visível ao usuário final) da aplicação, sendo que para ter o mesmo resultado precisará ser gasto muito mais tempo de desenvolvimento.
A falta do uso das subconsultas pode acarretar em uma série de contratempos na produção do software. Entre as desvantagens, podemos citar o crescimento do código fonte do sistema, que consequentemente sofrerá também um aumento no tempo de desenvolvimento, acarretando em um maior custo final do programa.
Modelagem do banco
Para exemplificar o uso das subconsultas iremos expor algumas situações sujeitas a acontecer no cotidiano de DBA’s e programadores. O modelo do banco de dados proposto é para o uso em um supermercado, como apresenta a Figura 1.
Figura 1. Modelo relacional do banco.
Neste banco de dados, temos primeiramente a tabela produtos, onde estarão cadastradas todas as mercadorias do supermercado. A tabela venda armazenará tudo o que foi vendido no estabelecimento. O relacionamento desta tabela com a primeira tabela (produto) acaba gerando uma outra, pois o seu relacionamento é N..N, uma vez que um produto pode estar em várias vendas e uma venda poderá ter vários produtos. Neste caso foi dada a origem a tabela ItemVenda, onde serão encontrados quais os produtos participaram de uma determinada venda. Finalmente, temos a tabela caixa, que faz a ligação com venda gerando um relacionamento N..1, pois um caixa realiza várias vendas, enquanto que uma venda só pode ser realizada por apenas um caixa.
Criando o banco
Segue na Listagem 1 o script para criação do banco de dados, feito no Interbase.
Listagem 1. Script para criação do Banco de Dados
create table produto(
cod_produto integer not null, nome varchar(45),
peso integer, preco float,categoria varchar(45),
constraint pkproduto primary key (cod_produto));
create table caixa(
cod_caixa integer not null, num_caixa integer,
constraint pkcaixa primary key (cod_caixa));
create table venda(
cod_venda integer not null, cod_caixa integer not null,
data date, total float,
constraint pkvenda primary key (cod_venda, cod_caixa),
constraint fkvendacaixa foreign key (cod_caixa) references caixa(cod_caixa));
create table itemvenda(
cod_produto integer not null, cod_venda integer not null,
cod_caixa integer not null, valor float, qtde integer,
constraint pkitemvenda primary key (cod_produto, cod_venda, cod_caixa),
constraint fkitemvendaproduto foreign key (cod_produto) references produto(cod_produto),
constraint fkitemvendavenda foreign key (cod_venda, cod_caixa)
references venda(cod_venda, cod_caixa));
...