Um breve mergulho na semântica SQL

Definindo os tipos

Consideremos os tipos fundamentais representados por t, onde t pode ser num ou str. Definamos então o tipo coluna<t> para que possamos construir o tipo tabela< coluna<t1>, coluna<t2>, ... >, que é o tipo básico da SQL. Ou seja, o tipo tabela é composto por uma sequência de tipos coluna, cada um com seu próprio tipo fundamental.

Consultas

O bloco para se executar uma consulta é formado pelas palavras chaves select, from e where, nesta ordem.

O resultado de uma consulta é uma tabela result, cujo tipo é tabela< type(cols[0]), type(cols[1]), ... >.

Cada objeto da lista cols deve pertencer à sequência de colunas de tab. O caractere * representa uma lista de colunas que contem todas as colunas de tab.

Se a cláusula where for omitida, todas as linhas de tab farão parte de result.

Variáveis

O escopo de uma consulta é definido na cláusula from. Desta forma, podemos instanciar variáveis para nos referirmos às tabelas.

Operações entre tabelas

Produto cartesiano

Sintaxe: <tabela>, <tabela><tabela>

Sejam as tabelas A do tipo tabela< colunaA1, ... > e B do tipo tabela< colunaB1, ... >. O produto cartesiano de A com B resulta em uma tabela do tipo tabela< colunaA1, ..., colunaB1, ... >.

À medida que encadeamos produtos cartesianos, o custo de memória aumenta muito rapidamente. Isto ocorre porque o produto cartesiano normalmente gera muitas linhas desinteressantes. Embora nós possamos filtrar as linhas que importam com a cláusula where, a memória do servidor já foi drasticamente consumida pelo SGBD. Devido a este fato, uma boa prática é utilizar o

inner join

Sintaxe: <tabela> inner join <tabela> on <condição de emparelhamento><tabela>

O inner join permite que filtremos as linhas de um produto cartesiano antes que elas passem a compor a tabela resultante.

A análise semântica é a mesma do produto cartesiano.

left join e right join

Se quisermos que a tabela resultante contenha todas as linhas de uma das tabelas do join mesmo que não haja correspondência para satisfazer a condição de emparelhamento, utilizamos left join ou right join. As células sem elementos correspondentes são preenchidas com objetos nulos.

Sintaxes e análises semânticas análogas ao inner join.

union

Sintaxe: <tabela> union <tabela><tabela>

O operador union requer que as tabelas fornecidas sejam do mesmo tipo, ou seja

Os nomes das colunas da tabela resultante são os nomes das colunas da primeira tabela.

Condições

=, <> ou!=, >, >=, < e <=

Operadores utilizados para fazermos comparações entre objetos do mesmo tipo básico. No tipo str, a magnitude considerada é a ordem alfabética.

in

Retorna true se um objeto pertence à lista em questão.

Se uma <tabela> possui apenas uma coluna, ela pode ser utilizada como uma lista.

A negação de in é not in.

Funções de agregação

Para melhorar a legibilidade das consultas que incluem funções de agregação, nós daremos nomes fictícios às colunas resultantes com o auxílio da palavra-chave as.

count

Computa a quantidade de objetos não nulos da coluna escolhida. Um cuidado extra é requerido para usar count em tabelas provenientes de left join ou right join.

Caso não importe se a tabela tenha ou não objetos nulos, podemos utilizar count(*).

min e max

Computam respectivamente o mínimo e o máximo valor de uma coluna. Em colunas cujo tipo básico é str, a magnitude considerada é a ordem alfabética.

sum e avg

Funções utilizadas exclusivamente em colunas cujo tipo básico é num. Elas computam respectivamente a soma e a média dos valores da coluna.

group by

As funções de agregação normalmente são utilizadas para gerar tabelas com apenas uma linha.

Mas nós podemos utilizar group by para que os resultados das funções de agregação sejam computados em blocos isolados. Para isto, à exceção da coluna elegida para o group by, todas as outras colunas mencionadas na cláusula select devem gerar apenas uma linha, como é o caso das funções de agregação.

Links recomendados