Desmistificando O SELECT no SQL SERVER: O FROM

E após mais um longo tempo sem postar nada,  vou dando continuidade a nossa série do processamento lógico de um SELECT

Hoje vamos falar sobre o FROM. Neste post eu tentei uma breve explicação sobre o que é o processamento lógico, e a comparação dele com o processamento físico. O objetivo desta série é saber como o SQL Server “entende” uma query e como ele vai manipular as informações para produzir o resultado codificado pelo seu comando de SELECT. De posse desta informação, você pode começar a manipular suas queries e entender porque determinada consulta não está trazendo um resultado que você espera, ou rapidamente poder montar uma consulta que irá trazer os dados corretamente.

A cláusula FROM

A cláusula FROM é a primeira a ser processada. Lá ficam as nossas tabelas e as operações que fazemos com elas.Você pode fazer JOINS, APPLYs e PIVOTs com as tabelas. A fase de processamento do FROM é divido em sub-fases, pois é possível realizar várias operações dentro do JOIN (JOINS, APPLY e PIVOTS). Cada sub-fase também produz uma tabela virtual que é passada para a próxima sub-fase e por ai em diante. No final, a tabela virtual resultante é retornada do FROM e passada para a próxima fase,que é o WHERE (que veremos em outro post). Esta imagem ilustra melhor:

Cada sub-fase do FROM gera uma tabela virtual que é passada para a próxima sub-fase. A última sub-fase gera a tabela virtual do FROM.

Cada sub-fase do FROM gera uma tabela virtual que é passada para a próxima sub-fase. A última sub-fase gera a tabela virtual do FROM.

A sintaxe do FROM é a seguinte:

FROM
input OPERAÇÃO input OPERAÇÃO input OPERAÇÃO input [etc…]

Percebam que eu usei o nome “input”. Vou chamar assim porquê esse input pode ser qualquer coisa que retorne uma estrutura de tabela:

  • Uma tabela
  • Uma view
  • Uma tabela derivada
  • Uma CTE
  • Uma Table-Valued Function

Se você não conhece o que são cada um desses itens, não se preocupe. Apenas mantenham em mente que “input” é uma tabela.

A OPERACAO é o que será feito entre os dois inputs. Ela pode ser:

  • JOINS (CROSS,INNER, LEFT, RIGHT,FULL)
  • APPLY (CROSS, OUTER)
  • PIVOT (PIVOT, UNPIVOT)

        As sub-fases da cláusula FROM variam de acordo com cada uma dessas oparações. A sub-fases para um “INNER JOIN” são diferentes para um CROSS JOIN que são diferentes para um “CROSS APPLY” ou um “UNPIVOT”.
Para simplificar, vamos inicialmente falar somente sobre as sub-fases para todos os tipos de JOINS, pois estes são mais fáceis de se compreender e são usados mais frequentemente. Em outro post entraremos em mais detalhes sobre as sub-fases dos outros operadores. Mas o fluxo sempre será o mesmo: o resultado produzido por uma fase, será passado a próxima fase. No FROM, existe uma sub-fases para cada operador de tabela.

Operadores de Tabela

As operações realizada com as tabelas são feitas através de operadores de tabela. Por exemplo, um “INNER JOIN”. Os operadores de tabela seguem algumas regras já conhecida por nós lá na matemática…Por exemplo, você tem a operação “SOMAR”. O que é preciso para fazer uma soma acontecer? Você precisa de 2 números para fazer a SOMA. Neste caso, os 2 números chamamos de “operando” e a “soma” é o operador, o qual é representado pelo sinal “+”. Com tabelas é a mesma coisa. Por exemplo, para fazer um CROSS JOIN, você precisa de dois inputs (duas tabelas). O operador é representado pelo seu próprio nome, ou seja, “CROSS JOIN”. Os dois inputs (as duas tabelas) são os nossos operandos.

Algumas operadores da matemática em comparação com operadores de tabela

Alguns operadores da matemática em comparação com operadores de tabela

Ainda na matemática, se você tem a expressão “1 + 1 + 2″, Você pode fazer “1 + 1″, e do resultado, somar com 2. Ou seja o operador só trabalha com 2 operandos por vez. Igualmente com os operadores de tabela, se existir mais de 2 operandos, é feito a operação entre os 2 primeiros operandos, e o resultado é usado como input da esquerda para o próximo operador, juntamente com o outro input da direita, e por ai vai até acabar:

input_A OPERADOR input_B OPERADOR input_C OPERADOR input_D:

    input_A OPERADOR input_B  = input_AB

    input_AB OPERADOR input_C = input_ABC

    input_ABC OPERADOR input_D = input_ABCD

Como acabou as operações, o resultado seria o “input_ABCD”.

Percebam que o resultado produzido por um operador é usado como input para a próxima operação

Percebam que o resultado produzido por um operador é usado como input para a próxima operação

Lembre-se que podemos misturar operadores de diferentes operações:

A JOIN B APPLY C PIVOT D.

Simplesmente, o resultado do JOIN de A com B é usado para fazer o APPLY com C, e este último resultado é usado para fazer o PIVOT com D.

Existem três grupos de operadores de tabela no SQL Server: JOINS, APPLY e PIVOT. Os Joins combinam linhas de dois inputs, e podem se basear em um condição. O APPLY também combina linhas entre dois inputs, porém ele é um pouco mais avançado e permite executar sub-queries para cada linha. O PIVOT permite transformar linhas em colunas e vice-versa. Para cada uma dessas classes, há algumas sub-fases que são executadas. Isto significa que para cada operador que você usa em sua query, 1 ou mais sub-fases dessas serão executadas. Lembre-se, as sub-fases são executadas para cada operador usado na query. Dependendo do operador usado, algumas sub-fases não precisarão ser executadas e o SQL Server irá avançar para o próximo operador ou finalizar o FROM, caso não haja mais operadores. Mas, de novo, ressalto que por enquanto iremos apenas falar de JOINs.

Na imagem acima podemos observar o que foi dito anteriormente: Cada operador irá executar as sub-fases correspondentes ao seu grupo.

Na imagem acima podemos observar o que foi dito anteriormente: Cada operador irá executar as sub-fases correspondentes ao seu grupo.

AS SUB-FASES DO JOIN

  • 1ª Sub-Fase: Produto cartesiano
    Nesta sub-fase todas as linhas da tabela da esquerda são combinadas com todas as linhas da tabela da direita. O operador CROSS JOIN executa somente sub-fase.
  • 2ª Sub-Fase: Aplicar a “condição” da cláusula ON
    Alguns tipos de JOINS permite que você especifique uma condição, através da cláusula “ON”. Para cada linha resultante da fase anterior, a condição ON será executada e o seu resultado, que só pode ser VERDADEIRO ou FALSO, será salvo em uma coluna interna. Somente as linhas onde o valor for VERDADEIRO serão mantidas e passadas para a próxima fase. O operador “INNER JOIN” executa somente até esta sub-fase.
  • 3ª Sub-Fase: Devolver as “linhas preservadas”
    Alguns joins permitem que todas as linhas das tabelas envolvidas na operação sejam preservadas, mesmo se o filtro ON resultar em FALSO para todas elas. Essas são os OUTERS JOINS (LEFT JOIN, RIGHT JOIN e FULL JOIN). Nesta fase as linhas das tabelas que devem ser preservadas são adicionadas de volta ao resultado. Os operadores “OUTER” mencionados acima executam até esta sub-fase.

Nos próximos posts, vamos detalhar cada uma destas sub-fases. Até lá!

[]’s
Rodrigo Ribeiro Gomes
MCTS | MCITP