Pergunta

cruz uma junção executa um produto cartesiano nas tuplas dos dois conjuntos.

SELECT *
FROM Table1
CROSS JOIN Table2

Que as circunstâncias tornam tal operação SQL particularmente útil?

Foi útil?

Solução

Se você tem um "grid" que você deseja preencher completamente, como tamanho e informações de cor para um determinado artigo de roupa:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Talvez você quer uma tabela que contém uma linha para cada minuto do dia, e você quiser usá-lo para verificar que um procedimento foi executado a cada minuto, de modo que 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 você deseja aplicar a cada mês do ano:

select
    specId,
    month
from
    reports CROSS JOIN months

O problema com mantendo-os como pontos de vista é que na maioria dos casos, você não quer que um produto completo, particularmente com respeito à roupa. Você pode adicionar lógica MINUS à consulta para remover certas combinações que você não levar, mas você pode achar mais fácil para 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 têm talvez algumas mais linhas do que você pensou, ou talvez sua cláusula WHERE foi parcialmente ou completamente ausente. Nesse caso, o DBA irá notificá-lo imediatamente da omissão. Normalmente, ele ou ela não será feliz.

Outras dicas

Você está normalmente não vai querer um produto cartesiano completo para a maioria das consultas de banco de dados. Todo o poder de bancos de dados relacionais é que você pode aplicar o que quer restrições que você pode estar interessado em que lhe permitem evitar puxar linhas desnecessárias do db.

Suponho que um exemplo artificial onde você pode querer isto é, se você tem uma tabela de funcionários e uma mesa de postos de trabalho que precisam fazer e quer ver todos os projetos possíveis de um funcionário para um trabalho.

Gerar dados para testar.

Ok, isso provavelmente não vai responder à pergunta, mas, se é verdade (e eu nem tenho certeza de que) é um pouco divertido da história.

Nos primeiros dias de Oracle, um dos desenvolvedores percebeu que precisava para duplicar a cada linha em uma tabela (por exemplo, é possível que era uma tabela de eventos e ele precisava mudar-lo separado "start evento" e " acabar com entradas de eventos"). Ele percebeu que, se ele tinha uma mesa com apenas duas linhas, ele poderia fazer uma junção cruzada, selecionando apenas as colunas na primeira tabela e obter exatamente tinha que precisava. Então ele criou uma tabela simples, que ele naturalmente chamado "DUAL".

Mais tarde, ele precisa fazer algo que só poderia ser feito através de um select de uma tabela, mesmo que a ação em si não tinha nada a ver com a mesa, (talvez ele esqueceu o relógio e queria ler o tempo via SELECIONAR SYSDATE FROM ...) ele percebeu que ele ainda tinha sua mesa DUAL em torno de mentir, e usou isso. Depois de um tempo, ele cansado de ver o tempo impressa duas vezes, então ele eventual excluída uma das linhas.

Outros da Oracle começou a usar sua mesa, e, eventualmente, decidiu-se incluí-lo na instalação padrão do Oracle.

O que explica por uma mesa cuja única importância é que ele tem uma linha tem um nome que significa "dois".

A chave é "me mostrar todas as combinações possíveis". Eu usei isso em conjunto com outros campos calculados um então classificadas / filtrada aqueles.

Por exemplo, digamos que você está construindo uma aplicação de arbitragem (trading). Você tem vendedores oferecendo produtos a um preço e compradores pedindo produtos a um custo. Você fizer uma junção cruzada sobre a chave do produto (para igualar-se os potenciais compradores e vendedores), calcular o spread entre custo e preço, em seguida, classificar desc. sobre isso para dar-lhe (o intermediário) os comércios mais lucrativos para executar. Quase sempre você vai ter outros critérios de filtro delimitadora de curso.

Toma algo como uma tabela de dígitos, que tem linhas dez para os dígitos 0-9. Você pode usar junção cruzada na mesa algumas vezes para um resultado get que tem no entanto muitas linhas que você precisa, com os resultados numerados de forma adequada. Isto tem um número de utilizações. Por exemplo, você pode combiná-lo com uma função datadd () para obter um conjunto para cada dia em um determinado ano.

Esta é uma maneira interessante de usar uma junção cruzada para criar um relatório de tabela de referência cruzada . Encontrei-o em de Joe Celko SQL para Smarties , e tê-lo usado várias vezes. Ele faz ter um pouco de configuração, mas tem valido a pena o tempo investido.

Imagine que você teve uma série de perguntas que você quer emitir mais de uma combinação específica de itens e datas (preços, disponibilidade, etc ..). Você poderia carregar os itens e datas em tabelas temporárias separadas e têm suas consultas atravessar unir as tabelas. Isto pode ser mais conveniente do que a alternativa de enumerar os itens e datas em cláusulas, especialmente porque alguns bancos de dados limitar o número de elementos em uma cláusula IN.

Você pode usá-lo CROSS JOIN para: - gerar dados para fins de teste - combinam todas as propriedades - você precisa de todas as combinações possíveis por exemplo grupos sanguíneos (A, B, ..) com Rh - / +, etc ... - ajustá-lo para seus propósitos;) - eu 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;
  • criar uma junção para 2 tabelas sem um ID comum e, em seguida, agrupá-lo usando max (), etc .. para encontrar maior combinação possível
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top