Uma junção cruzada executa um produto cartesiano nas tuplas dos dois conjuntos.
SELECT *
FROM Table1
CROSS JOIN Table2
Quais circunstâncias tornam essa operação SQL particularmente útil?
Uma junção cruzada executa um produto cartesiano nas tuplas dos dois conjuntos.
SELECT *
FROM Table1
CROSS JOIN Table2
Quais circunstâncias tornam essa operação SQL particularmente útil?
Respostas:
Se você tiver uma "grade" que deseja preencher completamente, como informações de tamanho e cor de uma determinada peça de roupa:
select
size,
color
from
sizes CROSS JOIN colors
Talvez você queira uma tabela que contenha uma linha para cada minuto do dia e queira usá-la para verificar se um procedimento foi executado a cada minuto, então você pode cruzar três tabelas:
select
hour,
minute
from
hours CROSS JOIN minutes
Ou você tem um conjunto de especificações de relatório padrão que deseja aplicar a todos os meses do ano:
select
specId,
month
from
reports CROSS JOIN months
O problema em mantê-los como visualizações é que, na maioria dos casos, você não quer um produto completo, principalmente no que diz respeito a roupas. Você pode adicionar MINUS
lógica à consulta para remover certas combinações que você não carrega, mas você pode achar mais fácil preencher uma tabela de outra forma e não usar um produto cartesiano.
Além disso, você pode acabar tentando a junção cruzada em tabelas que talvez tenham mais algumas linhas do que você pensava ou talvez sua WHERE
cláusula esteja parcial ou totalmente ausente. Nesse caso, seu DBA irá notificá-lo imediatamente sobre a omissão. Normalmente, ele ou ela não ficará feliz.
Gere dados para teste.
Normalmente, você não vai querer um produto cartesiano completo para a maioria das consultas de banco de dados. Todo o poder dos bancos de dados relacionais é que você pode aplicar quaisquer restrições nas quais possa estar interessado para evitar a extração de linhas desnecessárias do banco de dados.
Suponho que um exemplo inventado em que você pode querer isso é se você tem uma tabela de funcionários e uma tabela de trabalhos que precisam ser feitos e deseja ver todas as atribuições possíveis de um funcionário para um trabalho.
Ok, isso provavelmente não vai responder à pergunta, mas, se for verdade (e eu nem tenho certeza disso), é um bocado divertido de história.
Nos primeiros dias da Oracle, um dos desenvolvedores percebeu que precisava duplicar todas as linhas de uma tabela (por exemplo, é possível que fosse uma tabela de eventos e ele precisou alterá-la separadamente "evento inicial" e "evento final" entradas). Ele percebeu que se tivesse uma tabela com apenas duas linhas, ele poderia fazer uma junção cruzada, selecionando apenas as colunas na primeira tabela, e obter exatamente o que precisava. Então ele criou uma mesa simples, que ele chamou naturalmente de "DUAL".
Mais tarde, ele precisa fazer algo que só poderia ser feito por meio de um select de uma tabela, embora a ação em si não tivesse nada a ver com a tabela (talvez ele tenha esquecido o relógio e quisesse ler a hora via SELECT SYSDATE FROM .. .) Ele percebeu que ainda tinha sua mesa DUAL ao redor e a usou. Depois de um tempo, ele se cansou de ver a hora impressa duas vezes, então acabou apagando uma das linhas.
Outros na Oracle começaram a usar sua tabela e, eventualmente, decidiu-se incluí-la na instalação padrão do Oracle.
O que explica por que uma tabela cujo único significado é ter uma linha tem um nome que significa "dois".
A chave é "mostre-me todas as combinações possíveis". Usei-os em conjunto com outros campos calculados e os classifiquei / filtrou.
Por exemplo, digamos que você esteja criando um aplicativo de arbitragem (negociação). Você tem vendedores oferecendo produtos a um preço e compradores pedindo produtos a um custo. Você faz uma junção cruzada na chave do produto (para combinar os compradores e vendedores em potencial), calcula a diferença entre custo e preço e classifica desc. sobre isso para dar a você (o intermediário) as negociações mais lucrativas para executar. Quase sempre você terá outros critérios de filtro delimitadores, é claro.
É algo como uma tabela de dígitos, que possui dez linhas para os dígitos de 0 a 9. Você pode usar a junção cruzada nessa tabela algumas vezes para obter um resultado que tenha quantas linhas forem necessárias, com os resultados numerados apropriadamente. Isso tem vários usos. Por exemplo, você pode combiná-lo com uma função datadd () para obter um conjunto para todos os dias de um determinado ano.
Esta é uma maneira interessante de usar uma junção cruzada para criar um relatório de crosstab . Eu o encontrei no SQL For Smarties de Joe Celko e o usei várias vezes. É preciso um pouco de configuração, mas valeu a pena o tempo investido.
Imagine que você tenha uma série de consultas que deseja fazer sobre uma combinação específica de itens e datas (preços, disponibilidade, etc.). Você pode carregar os itens e as datas em tabelas temporárias separadas e fazer com que suas consultas se juntem às tabelas. Isso pode ser mais conveniente do que a alternativa de enumerar os itens e datas nas cláusulas IN, especialmente porque alguns bancos de dados limitam o número de elementos em uma cláusula IN.
você pode usá-lo CROSS JOIN para: - gerar dados para fins de teste - combinar todas as propriedades - você precisa de todas as combinações possíveis de, por exemplo, grupos sanguíneos (A, B, ..) com Rh - / +, etc ... --tune-o para seus propósitos;) - Não sou especialista nesta área;)
CREATE TABLE "HR"."BL_GRP_01"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);
CREATE TABLE "HR"."BL_GRP_02"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);
CREATE TABLE "HR"."RH_VAL_01"
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);
select distinct a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;