curso
Produto cartesiano em SQL: Um guia abrangente
O produto cartesiano é um conceito fundamental do SQL que pode ser poderoso e complexo. Entender como usá-lo de forma eficaz pode melhorar muito seus recursos de manipulação de dados. Neste guia, exploraremos os prós e contras dos produtos cartesianos, fornecendo insights e exemplos práticos.
Para os iniciantes em SQL, considere começar com nosso curso SQL Intermediário para criar uma base sólida. Além disso, a Folha de dicas básicas de SQL, que você pode baixar, é uma referência útil porque contém todas as funções SQL mais comuns.
O que é um produto cartesiano?
O produto cartesiano no SQL é o resultado da combinação de todas as linhas de uma tabela com todas as linhas de outra. Na maioria das vezes, essa operação é gerada por meio de um CROSS JOIN
, formando um conjunto de resultados que contém todos os pares possíveis de linhas das duas tabelas. Embora seja eficiente, pode levar a conjuntos de resultados muito grandes, especialmente ao trabalhar com tabelas que contêm muitas linhas, portanto, deve ser usado com cautela. Na verdade, aposto que muitos desenvolvedores provavelmente descobriram os produtos cartesianos da maneira mais difícil, omitindo acidentalmente uma condição de junção de algum tipo, apenas para acabar com um conjunto de resultados enorme.
Histórico matemático
Em matemática, um produto cartesiano (denotado como A × B) é um conjunto de todos os pares ordenados possíveis criados pelo emparelhamento de cada elemento do conjunto A com cada elemento do conjunto B. Em SQL, isso se traduz em emparelhar cada linha de uma tabela com cada linha de outra.
Exemplo de produto cartesiano. Imagem do autor.
Junção cruzada SQL
A operação de junção cruzada no SQL cria um produto cartesiano entre duas tabelas, juntando cada linha da primeira tabela com cada linha da segunda. Como resultado, a junção cruzada gera todas as combinações de linhas possíveis para os dados. Vejamos um exemplo de execução de uma operação de junção cruzada no SQL.
Suponha que você tenha duas tabelas, Students
e Courses
:
Mesa dos alunos
nome | grau |
---|---|
Alice | 10 |
Bob | 11 |
Charlie | 12 |
Tabela de cursos
curso | nível |
---|---|
Matemática | Básico |
Ciência | Avançado |
História | Intermediário |
Na consulta a seguir, cada aluno é emparelhado com cada curso, mostrando suas notas e níveis de dificuldade.
-- Perform the cross join to list each student with every course
SELECT Students.name, Students.grade, Courses.course, Courses.level
FROM Students
CROSS JOIN Courses;
Exemplo de produto cartesiano em SQL resultante de junção cruzada. Imagem do autor.
Quando usar e não usar o produto cartesiano no SQL
O produto cartesiano no SQL pode ser muito útil quando o comportamento é compreendido e usado intencionalmente. Vamos examinar os casos de uso (e as possíveis armadilhas) do uso do produto cartesiano.
Casos de uso
Veja a seguir os cenários em que o uso do produto cartesiano pode ser útil:
- Geração de combinações: Um produto cartesiano é ideal para gerar todas as combinações de dois conjuntos de valores. Por exemplo, você pode querer associar produtos a descontos, associar funcionários a turnos ou criar todas as associações possíveis entre diferentes categorias.
- Cenários de teste: Ao executar casos de teste, um produto cartesiano pode ser útil para simular todos os cenários possíveis, combinando vários conjuntos de parâmetros ou configurações.
- Preenchimento de dados faltantes: Um produto cartesiano também pode ajudar a identificar lacunas, gerando todas as combinações possíveis e, em seguida, unindo os resultados à esquerda para encontrar entradas ausentes, como datas ausentes em uma análise de série temporal.
Possíveis armadilhas
Embora o produto cartesiano seja útil para alguns cenários, há alguns riscos, que incluem os seguintes:
- Problemas de desempenho: Como um produto cartesiano multiplica as linhas de uma tabela com as de outra, o resultado pode crescer exponencialmente. Se o conjunto de dados for muito grande, isso pode levar a tempos de execução de consulta lentos, uso excessivo de memória e até mesmo a falhas no banco de dados.
- Duplicação de dados não intencional: Sem uma filtragem cuidadosa, os produtos cartesianos podem produzir linhas que parecem duplicadas ou irrelevantes para a análise, levando a interpretações de dados distorcidas ou resultados incorretos se as duplicatas não forem esperadas ou gerenciadas corretamente.
- Depuração difícil: Produtos cartesianos não intencionais, como o esquecimento de especificar uma condição de união, podem levar a uma união cruzada em vez de uma união interna ou externa. Isso pode resultar em resultados inesperados que podem ser difíceis de rastrear e corrigir.
Aplicações reais do produto cartesiano
Embora o produto cartesiano possa ser usado com moderação devido aos riscos potenciais, ele é útil em cenários em que você precisa combinar todos os pares possíveis de elementos de dados.
Cenários de combinação de dados
O produto cartesiano é útil para calcular métricas de desempenho relativo, analisar a compatibilidade ou criar sistemas de classificação. Quando você precisar comparar todos os elementos em dois conjuntos de dados, poderá usar o produto cartesiano para emparelhar cada item com todos os outros itens.
Por exemplo, para comparar o desempenho de cada funcionário com o de todos os outros funcionários, o produto cartesiano criaria todos os pares de funcionários possíveis:
-- Select two columns with employee names from the Employees table
SELECT
A.employee_name AS Employee1,
B.employee_name AS Employee2
FROM Employees AS A
-- Cross join to create all possible pairs of employees
CROSS JOIN Employees AS B;
O produto cartesiano também é importante na análise de comércio eletrônico para explorar toda a gama de combinações de produtos e descontos. Suponha que você tenha tabelas para Products
e Discounts
, uma junção cruzada poderia criar uma lista de todas as combinações de desconto de produto:
-- Select product names and discount types
SELECT
Products.product_name,
Discounts.discount_type
FROM Products
-- Generate all product and discount combinations
CROSS JOIN Discounts;
Testes e validação
Um produto cartesiano permite a criação de todas as possíveis combinações de parâmetros em ambientes de teste, o que é essencial para testes de cenários abrangentes. Por exemplo, se você estiver testando um sistema com várias configurações de sistema operacional, dispositivo e navegador, o uso de uma união cruzada garante que todas as configurações possíveis sejam testadas.
-- Select combinations of operating systems, devices, and browsers
SELECT
OS.name AS OperatingSystem,
Device.name AS Device,
Browser.name AS Browser
FROM OperatingSystems AS OS
-- All combinations with devices
CROSS JOIN Devices AS Device
-- All combinations with browsers
CROSS JOIN Browsers AS Browser;
Um produto cartesiano pode ajudar a identificar registros ausentes, o que o torna útil para garantir a integridade dos dados. Por exemplo, ao analisar dados de vendas diárias e confirmar a existência de dados para cada produto todos os dias, você pode criar um produto cartesiano das tabelas Products
e Dates
. Em seguida, você pode unir à esquerda os dados reais de vendas para identificar qualquer entrada de data-produto ausente.
-- Select dates and products with no sales
SELECT
Dates.date,
Products.product_name,
Sales.sales_amount
FROM Dates
-- Create all date and product combinations
CROSS JOIN Products
-- Match sales by date and product
LEFT JOIN
Sales ON Dates.date = Sales.date
AND Products.product_name = Sales.product_name
-- Filter for combinations with no sales
WHERE Sales.sales_amount IS NULL;
Algumas ideias sobre desempenho
Como os produtos cartesianos geram possíveis combinações de dados entre duas tabelas, pode haver problemas significativos de desempenho quando há tabelas grandes envolvidas. Sugiro as seguintes técnicas para otimização de consultas e gerenciamento de grandes conjuntos de dados para melhorar o desempenho do banco de dados.
Otimização de consultas
Considere os seguintes métodos para escrever consultas eficientes que envolvam produtos cartesianos.
-
Limite a contagem de linhas antes da união: Para reduzir o número de linhas envolvidas no produto cartesiano, aplique filtros a cada tabela antes de realizar a união cruzada. Por exemplo, use as cláusulas
WHERE
para filtrar cada tabela por critérios relevantes, minimizando o conjunto de dados resultante. -
Use SELECT com colunas específicas: Ao executar um produto cartesiano, especifique somente as colunas de que você precisa na cláusula
SELECT
para reduzir o uso da memória e melhorar o desempenho. Evite usar o siteSELECT *
, pois ele retorna todas as colunas, o que pode levar a resultados grandes e difíceis de manejar. -
Aplicar condições para converter uniões cruzadas em uniões internas: Se apenas determinadas combinações de linhas forem relevantes, considere adicionar condições adicionais de junção cruzada que funcionem como
INNER JOIN
. Isso ajuda a restringir a saída, limitando quais linhas de cada tabela devem ser emparelhadas. -
Processamento em lote: Para grandes conjuntos de dados, divida as consultas em partes gerenciáveis para processamento em lote. Isso pode evitar o estouro de memória e melhorar o tempo de resposta, especialmente quando você faz consultas em tabelas grandes.
Gerenciamento de grandes conjuntos de dados
Use as técnicas a seguir para gerenciar os grandes conjuntos de dados resultantes do uso de produtos cartesianos.
-
Indexação: Adicione índices em colunas unidas com frequência para melhorar o desempenho ao filtrar ou emparelhar tabelas grandes. Embora a indexação não acelere diretamente as uniões cruzadas, ela é útil quando você filtra ou une posteriormente o produto cartesiano a outras tabelas, permitindo que o banco de dados acesse as linhas mais rapidamente.
-
Particionamento de tabelas grandes: O particionamento de tabelas pode melhorar o desempenho de consultas que envolvem produtos cartesianos. O particionamento divide as tabelas em partes menores e mais gerenciáveis com base em colunas específicas, permitindo que o banco de dados leia somente as partições relevantes durante a execução da consulta.
-
Limitar linhas de resultado: Use a cláusula
LIMIT
para restringir o número de linhas retornadas nos casos em que você só precisa de uma amostra do produto cartesiano para fins de teste ou verificação. -
Use tabelas temporárias para resultados intermediários: Armazene os resultados intermediários em tabelas temporárias se você precisar reutilizar um produto cartesiano várias vezes para reduzir os novos cálculos e acelerar as operações subsequentes.
Outras operações SQL para ajudar
Em cenários em que a geração de um produto cartesiano completo pode não ser eficiente, existem métodos alternativos. Os métodos abaixo permitem que você alcance os resultados pretendidos sem sobrecarregar o banco de dados.
Junções internas e externas
Um INNER JOIN
retorna somente as linhas com uma correspondência entre as colunas especificadas em ambas as tabelas. Essa técnica limita o resultado a combinações relevantes e evita as várias linhas que vêm com um produto cartesiano. A junção interna é adequada quando você precisa apenas das linhas que atendem a critérios específicos em ambas as tabelas.
No exemplo abaixo, o site INNER JOIN
retorna apenas produtos e descontos que compartilham a mesma categoria.
-- Select products and corresponding discounts by category
SELECT
A.product_name,
B.discount_type
FROM Products AS A
-- Match products and discounts by category
INNER JOIN Discounts AS B ON A.category_id = B.category_id;
A união externa (LEFT JOIN
, RIGHT JOIN
e FULL JOIN
) retorna linhas correspondentes e não correspondentes de uma ou ambas as tabelas. Essa técnica é útil quando você deseja recuperar todas as linhas de uma tabela e todas as linhas correspondentes da outra, mas sem criar todas as combinações possíveis. A junção externa é adequada quando você deseja incluir dados sem correspondência para análise, mas não um emparelhamento cartesiano completo.
O site LEFT JOIN
na consulta abaixo retorna todos os produtos, inclusive aqueles sem um desconto correspondente, com valores NULL
para descontos não correspondentes.
-- Select products with corresponding discounts, (NULL if no matching discount)
SELECT
A.product_name,
B.discount_type
FROM Products AS A
-- Match products with discounts by category
LEFT JOIN Discounts AS B ON A.category_id = B.category_id;
Recomendo que você faça o curso Introdução ao SQL Server da DataCamp para saber mais sobre como unir tabelas e recuperar dados de várias tabelas.
Subconsultas e CTEs
As subconsultas permitem que você selecione dados específicos de uma tabela e os use para filtrar os resultados na consulta principal. Isso ajuda a evitar combinações desnecessárias de linhas, filtrando os dados apenas para as entradas relevantes. As subconsultas são úteis quando você precisa pré-filtrar dados ou calcular valores específicos para uso na consulta principal sem precisar de uma união cartesiana completa.
A subconsulta filtra os descontos com valores acima de 10 antes da união, reduzindo os dados processados e evitando uma união cruzada desnecessária.
-- Select products with discounts greater than 10 by category
SELECT
A.product_name,
B.discount
FROM Products AS A
-- Subquery to filter discounts over 10
INNER JOIN
(SELECT discount, category_id
FROM Discounts
WHERE discount > 10) AS B
-- Match products with filtered discounts by category
ON A.category_id = B.category_id;
Os CTEs, ou cláusulas WITH
, permitem que consultas complexas sejam divididas em etapas. Esse método ajuda a evitar produtos cartesianos, filtrando ou agregando dados antes da união. Os CTEs são apropriados para simplificar consultas em várias etapas, especialmente ao pré-agregar dados ou realizar várias uniões, mas você deseja evitar um resultado cartesiano completo.
A consulta abaixo usa uma expressão de tabela comum (CTE) para filtrar descontos maiores que 10 antes de unir os produtos com base na categoria.
-- Filter discounts and join with products by category
WITH FilteredDiscounts AS (
SELECT discount, category_id
FROM Discounts
WHERE discount > 10
)
SELECT
A.product_name,
FD.discount
FROM Products AS A
-- Join with filtered discounts by category
INNER JOIN
FilteredDiscounts AS FD ON A.category_id = FD.category_id;
Aplicações inovadoras do produto cartesiano
Embora o produto cartesiano seja amplamente usado em operações básicas de SQL, ele tem aplicações que vão além dos casos tradicionais de uso de banco de dados. Vamos ver como o produto cartesiano pode ser usado na preparação de dados de aprendizado de máquina e na geração de conjuntos de dados sintéticos para simulação.
Preparação de dados de aprendizado de máquina
Conjuntos de dados diversificados e abrangentes são importantes na preparação de dados para o aprendizado de máquina para treinar modelos robustos. Os produtos cartesianos podem criar um conjunto de dados completo que abrange todas as combinações possíveis de valores de recursos, permitindo que um modelo aprenda com uma gama mais ampla de cenários.
Por exemplo, ao criar modelos de detecção de fraude, você pode combinar tipos de transações, regiões e tipos de dispositivos para simular várias condições, ajudando o modelo a se generalizar em diferentes casos.
Geração de dados sintéticos
Os dados sintéticos são usados com frequência para testar sistemas em uma ampla gama de condições ou para proteger a privacidade, evitando o uso de dados reais. Os produtos cartesianos podem ajudar a gerar diversos conjuntos de dados sintéticos, que são úteis em aplicações que vão desde simulações até o aumento de dados para modelos de aprendizado de máquina.
Por exemplo, você pode combinar diferentes condições de mercado, taxas de juros e perfis de clientes em simulações financeiras para testar o desempenho de um modelo ou algoritmo em relação a essas variáveis.
Abaixo está um exemplo simples de como você pode criar dados sintéticos "do nada", por assim dizer, em SQL e, em seguida, usar um CROSS JOIN
para expandi-los em um conjunto de dados maior. A ideia é que cada pequena tabela represente uma dimensão de nossos dados de teste e, quando as unimos de forma cruzada, obtemos todas as combinações possíveis.
Exemplo 1: Combinação de várias dimensões
Suponha que você queira simular diferentes cenários financeiros com base em condições de mercado, taxas de juros e perfis de clientes. Podemos definir cada dimensão por meio de uma expressão de tabela comum (CTE) ou tabela temporária usando valores literais. Em seguida, o site CROSS JOIN
os mescla em todas as combinações possíveis:
WITH MarketConditions AS (
SELECT 'Bull' AS condition
UNION ALL
SELECT 'Bear'
UNION ALL
SELECT 'Sideways'
),
InterestRates AS (
SELECT 1.5 AS rate
UNION ALL
SELECT 2.0
UNION ALL
SELECT 3.25
),
CustomerProfiles AS (
SELECT 'Younger' AS profile
UNION ALL
SELECT 'Mid-career'
UNION ALL
SELECT 'Retired'
)
SELECT
mc.condition,
ir.rate,
cp.profile
FROM
MarketConditions mc
CROSS JOIN
InterestRates ir
CROSS JOIN
CustomerProfiles cp;
O conjunto de resultados terá 3×3×3 = 27 linhas. Cada linha é uma combinação única de condição de mercado, taxa de juros e perfil do cliente.
Exemplo de geração de dados sintéticos usando o produto cartesiano. Imagem do autor.
Exemplo 2: Geração de linhas usando sequências ou VALUES simples
Outra técnica é gerar um intervalo de números ou intervalos de tempo por meio da junção cruzada de pequenas tabelas com elas mesmas. Isso pode ser usado para produzir grandes volumes de linhas sintéticas para testes rápidos. Por exemplo, podemos usar a seguinte consulta para gerar os números de 1 a 10.
WITH
Nums AS (
SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
)
SELECT n
FROM Nums;
Usando o produto cartesiano para gerar linhas usando sequências. Imagem do autor.
Em seguida, podemos fazer a junção cruzada do mesmo conjunto de 10 linhas com ele mesmo para formar 10×10=100:
WITH
Nums AS (
SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
)
SELECT A.n AS n1, B.n AS n2
FROM Nums A
CROSS JOIN Nums B
ORDER BY A.n, B.n;
Para os resultados, você obterá 100 linhas, cada linha com um par de valores (n1,n2). Você pode estender essa lógica para centenas, milhares ou até milhões de linhas, mas esteja ciente do desempenho e do armazenamento.
Ao usar essas abordagens - CTEs (ou cláusulas VALUES
) para definições de dimensão e CROSS JOIN
para combinação - você pode criar rapidamente conjuntos de dados sintéticos em SQL sem depender de tabelas existentes.
Conclusão
A compreensão do produto cartesiano no SQL abre uma série de possibilidades para a manipulação e análise de dados. Ao dominar esse conceito, você pode aprimorar sua capacidade de trabalhar com conjuntos de dados complexos e otimizar as consultas ao banco de dados. Para obter insights mais avançados, considere nosso curso de habilidades SQL Server Fundamentals para aprofundar seus conhecimentos.
Dependendo da direção da sua carreira, recomendo que você se inscreva no curso de carreira de Analista de Dados Associado em SQL da DataCamp para aprender as habilidades necessárias no setor para se tornar um analista de dados ou experimente nosso curso de carreira de Engenheiro de Dados Associado em SQL para se tornar um engenheiro de dados.
Perguntas frequentes sobre produtos cartesianos
O que é um produto cartesiano no SQL?
Um produto cartesiano no SQL resulta de uma operação de junção cruzada, em que cada linha de uma tabela é combinada com cada linha de outra.
Como o produto cartesiano difere de outras uniões SQL?
Diferentemente de outras uniões, um produto cartesiano combina todos os pares possíveis de linhas das tabelas envolvidas, o que geralmente resulta em um grande conjunto de dados.
Quando devo usar um produto cartesiano?
Use um produto cartesiano quando você precisar gerar todas as combinações de linhas de duas tabelas, como em testes ou cenários analíticos específicos.
Quais são as considerações de desempenho para produtos cartesianos?
Os produtos cartesianos podem levar a grandes conjuntos de resultados, o que pode afetar o desempenho. Para atenuar isso, otimize as consultas e gerencie os conjuntos de dados com cuidado.
Existem alternativas ao uso de produtos cartesianos no SQL?
Sim, dependendo do caso de uso específico, as alternativas incluem o uso de uniões internas ou externas, subconsultas e expressões de tabela comuns.
Aprenda SQL com a DataCamp
curso
Manipulação de dados em SQL
programa
SQL para analistas de negócios
blog
O que é um banco de dados gráfico? Um guia para iniciantes
blog
Para que o SQL é usado? 7 Principais usos do SQL
tutorial
Exemplos e tutoriais de consultas SQL
tutorial
Como usar um alias SQL para simplificar suas consultas

Allan Ouko
9 min
tutorial
Introdução aos acionadores SQL: Um guia para desenvolvedores

Oluseye Jeremiah
13 min
tutorial