SQL Server – Utilizando o CROSS JOIN (produto cartesiano) para criação de linhas no resultado da consulta

Visualizações: 2.039
Tempo de Leitura: 4 minutos

Fala pessoal!
Nesse post eu gostaria de compartilhar com vocês o funcionamento de um operador que raramente vejo alguém utilizando, que é o CROSS JOIN, e que em determinados cenários, pode ter a sua utilidade.

O que é o CROSS JOIN?

O CROSS JOIN retorna a combinação de cada uma das linhas entre as tabelas envolvidas, também conhecido como Produto cartesiano, qual vou demonstrar abaixo para facilitar o entendimento.

Exemplo 1

Nesse exemplo vou criar 2 tabelas e cruzar os dados das duas tabelas para criar um produto cartesiano combinando cada linha da tabela #Sorvete com cada linha da tabela #Complemento (sim, estou com vontade de tomar sorvete).

Script para geração dos dados desse exemplo:

Resultado:

Pois bem, agora vamos criar o produto cartesiano entre as duas tabelas:

A única forma de se criar um produto cartesiano é utilizando CROSS JOIN?

Como pudemos observar, o produto cartesiano cria todas as combinações possíveis entre os dados envolvidos. Como no nosso exemplo era uma tabela de 3 registros em uma operação de CROSS JOIN com outra tabela de 4 registros, o nosso resultado final apresentou 12 linhas (3 x 4).

Se cada tabela tivesse 1.000 registros, o resultado final teria 1 milhão de registros (1.000 x 1.000), por isso o produto cartesiano geralmente não é algo desejável em uma operação de JOIN, e pode causar problemas de performance se ele ocorrer de forma não desejada (como em uma cláusula join errada, por exemplo)

Exemplo 2

Nesse exemplo, vou demonstrar um cenário prático onde o produto cartesiano justifica o seu uso, utilizando os organizadores e palestrantes do 1º SQL Day ES.

Script para geração dos dados desse exemplo:

Agora, eu quero mostrar como criar um relatório que me mostre sexo, estado e quantas pessoas temos nesse agrupamento:

Resultado:

Como vocês devem ter percebido, apenas os registros existentes na tabela são retornados. Por exemplo, no estado do “DF” só retornou resultados com o sexo “F”, pois na nossa tabela, existem apenas pessoas com o sexo Feminino no estado DF.

Mas e se eu quiser mostrar também os gêneros que que não possuem pessoas cadastradas na tabela? Como faço? Bem, para começar, vamos utilizar o CTE (Common Table Expressions) para combinar o gênero com as cidades e estados e criar todas as combinações possíveis:

Agora, vamos modificar esse script para nos retornar a quantidade de pessoas de cada uma das combinações, que é o que queremos mostrar no resultado da nossa query:

Resultado:

Conclusão

Bom pessoal, espero que eu tenha conseguido demonstrar que o produto cartesiano pode sim, ter sua utilidade no desenvolvimento de consultas T-SQL. Para criar o exemplo 2 sem utilizá-lo, teríamos que criar cursor ou loop while, o que tem uma péssima performance e a rotina acaba sendo bem mais complexa.

Embora eu tenha demonstrado um bom uso desse recurso, muito cuidado ao utilizá-lo, especialmente com grandes volumes de dados, uma vez que o CROSS JOIN ou produto cartesiano, cria todas as combinações possíveis entre 2 ou mais ResultSets, cruzando cada linha da tabela A com cada linha da tabela B.

Muitas vezes, observamos JOIN’s (INNER, LEFT, RIGHT) mal construídos e que acabam fazendo um produto cartesiano não intencional, gerando muitas linhas indesejadas e trazendo um problema de performance na consulta.

Dito isso, encerro esse post.
Um grande abraço pra vocês e até a próxima.