Каковы виды использования Cross Join? - PullRequest
96 голосов
/ 21 октября 2008

При перекрестном соединении выполняется декартово произведение на кортежи двух наборов.

SELECT *
FROM Table1
CROSS JOIN Table2

Какие обстоятельства делают такую ​​операцию SQL особенно полезной?

Ответы [ 9 ]

83 голосов
/ 21 октября 2008

Если у вас есть «сетка», которую вы хотите заполнить полностью, например информация о размере и цвете для определенного предмета одежды:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Возможно, вам нужна таблица, содержащая строку для каждой минуты дня, и вы хотите использовать ее для проверки выполнения процедуры каждую минуту, поэтому вы можете пересечь три таблицы:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Или у вас есть набор стандартных спецификаций отчетов, к которым вы хотите применять каждый месяц года:

select
    specId,
    month
from
    reports CROSS JOIN months

Проблема с сохранением этих представлений заключается в том, что в большинстве случаев вам не нужен законченный продукт, особенно в отношении одежды. Вы можете добавить MINUS логику в запрос, чтобы удалить определенные комбинации, которые вы не несете, но вам может быть проще заполнить таблицу другим способом и не использовать декартово произведение.

Кроме того, вы можете попытаться выполнить перекрестное соединение для таблиц, в которых, возможно, на несколько строк больше, чем вы думали, или, возможно, ваше предложение WHERE было частично или полностью отсутствует. В этом случае ваш администратор базы данных незамедлительно уведомит вас об упущении. Обычно он или она не будут счастливы.

13 голосов
/ 21 октября 2008

Как правило, вам не нужен полный декартовой продукт для большинства запросов к базе данных. Вся мощь реляционных баз данных заключается в том, что вы можете применять любые ограничения, которые могут вас заинтересовать, чтобы избежать вытягивания ненужных строк из БД.

Я полагаю, один надуманный пример, который вам может понадобиться, - это если у вас есть таблица сотрудников и таблица задач, которые нужно выполнить и которые хотят видеть все возможные назначения одного сотрудника на одну работу.

12 голосов
/ 21 октября 2008

Создание данных для тестирования.

11 голосов
/ 21 октября 2008

Хорошо, это, вероятно, не ответит на вопрос, но, если это правда (и я даже не уверен в этом), это забавная история.

В первые дни существования Oracle один из разработчиков понял, что ему нужно дублировать каждую строку в таблице (например, возможно, это была таблица событий, и ему нужно было изменить ее на отдельные «стартовое событие» и « конец события "записи). Он понял, что если бы у него была таблица с двумя строками, он мог бы выполнить перекрестное соединение, выбрав только столбцы в первой таблице, и получить именно то, что ему нужно. Поэтому он создал простую таблицу, которую он, естественно, назвал «ДВОЙНОЙ».

Позже ему нужно было сделать что-то, что можно было сделать только с помощью выбора из таблицы, даже если само действие не имело никакого отношения к таблице (возможно, он забыл свои часы и хотел прочитать время с помощью SELECT SYSDATE ОТ ...) Он понял, что у него все еще лежал ДВОЙНОЙ стол, и использовал это. Через некоторое время ему надоело видеть время, напечатанное дважды, поэтому он в конце концов удалил одну из строк.

Другие в Oracle начали использовать его таблицу, и в конце концов было решено включить ее в стандартную установку Oracle.

Что объясняет, почему таблица, единственное значение которой состоит в том, что она имеет одну строку, имеет имя, которое означает «два».

7 голосов
/ 21 октября 2008

Ключ «покажи мне все возможные комбинации». Я использовал их вместе с другими вычисляемыми полями, а затем отсортировал / отфильтровал их.

Например, скажем, вы создаете арбитражное (торговое) приложение. У вас есть продавцы, предлагающие товары по цене, и покупатели, запрашивающие товары по цене. Вы выполняете перекрестное соединение по ключу продукта (чтобы сопоставить потенциальных покупателей и продавцов), рассчитываете разницу между стоимостью и ценой, затем сортируете desc. Это дает вам (посреднику) наиболее выгодные сделки для исполнения. Конечно, почти всегда у вас будут другие критерии ограничивающего фильтра.

3 голосов
/ 21 октября 2008

Принимает что-то вроде таблицы цифр, которая имеет десять строк для цифр 0-9. Вы можете использовать перекрестное соединение в этой таблице несколько раз, чтобы получить результат, который содержит столько строк, сколько вам нужно, и результаты нумеруются соответствующим образом. Это имеет ряд применений. Например, вы можете объединить его с функцией datadd (), чтобы получить набор для каждого дня в данном году.

2 голосов
/ 21 октября 2008

Это интересный способ использования перекрестного соединения для создания отчета о перекрестной таблице . Я нашел его в SQL For Smarties Джо Селко и использовал его несколько раз. Это займет немного времени, но стоит потраченного времени.

1 голос
/ 01 марта 2019

вы можете использовать его CROSS JOIN для: - генерировать данные для тестирования - объединить все свойства - вам нужно все возможное сочетание, например, группы крови (A, B, ..) с Rh - / + и т. д. - настройте его для своих целей;) - Я не эксперт в этой области;)

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;
  • создать объединение для 2 таблиц без общего идентификатора, а затем сгруппировать его с помощью max () и т. Д., Чтобы найти максимально возможную комбинацию
1 голос
/ 21 октября 2008

Представьте, что у вас есть ряд запросов, которые вы хотите задать по определенной комбинации товаров и дат (цены, наличие и т. Д.). Вы можете загрузить элементы и даты в отдельные временные таблицы, и ваши запросы будут перекрестно соединяться с таблицами. Это может быть более удобным, чем альтернатива перечисления элементов и дат в предложениях IN, тем более что некоторые базы данных ограничивают количество элементов в предложении IN.

...