Перекрестное соединение выполняет декартово произведение кортежей двух наборов.
SELECT *
FROM Table1
CROSS JOIN Table2
Какие обстоятельства делают такую операцию SQL особенно полезной?
Перекрестное соединение выполняет декартово произведение кортежей двух наборов.
SELECT *
FROM Table1
CROSS JOIN Table2
Какие обстоятельства делают такую операцию SQL особенно полезной?
Ответы:
Если у вас есть «сетка», которую вы хотите заполнить полностью, например информацию о размере и цвете для определенного предмета одежды:
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
предложение частично или полностью отсутствует. В этом случае ваш администратор баз данных незамедлительно уведомит вас об упущении. Обычно он или она не будут счастливы.
Сгенерируйте данные для тестирования.
Обычно вам не понадобится полный декартово произведение для большинства запросов к базе данных. Вся сила реляционных баз данных заключается в том, что вы можете применять любые ограничения, которые могут вас заинтересовать, чтобы избежать извлечения ненужных строк из базы данных.
Я предполагаю, что есть один надуманный пример, когда вы можете захотеть, если у вас есть таблица сотрудников и таблица вакансий, которые нужно выполнить, и вы хотите увидеть все возможные назначения одного сотрудника на одну работу.
Хорошо, это, вероятно, не ответит на вопрос, но, если это правда (а я даже не уверен в этом), это забавная история.
На заре Oracle один из разработчиков понял, что ему нужно дублировать каждую строку в таблице (например, возможно, это была таблица событий, и ему нужно было изменить ее отдельно «начальное событие» и «конечное событие») записи). Он понял, что если бы у него была таблица с двумя строками, он мог бы выполнить перекрестное соединение, выбрав только столбцы в первой таблице, и получить именно то, что ему было нужно. Поэтому он создал простую таблицу, которую, естественно, назвал «ДВОЙНОЙ».
Позже ему нужно сделать что-то, что можно было бы сделать только с помощью выбора из таблицы, даже если само действие не имело ничего общего с таблицей (возможно, он забыл свои часы и хотел прочитать время с помощью SELECT SYSDATE FROM .. .) Он понял, что у него все еще валяется его ДВОЙНОЙ стол, и использовал его. Через некоторое время ему надоело видеть, как время печатается дважды, поэтому он в конце концов удалил одну из строк.
Другие в Oracle начали использовать его таблицу, и в конце концов было решено включить ее в стандартную установку Oracle.
Это объясняет, почему таблица, единственное значение которой состоит в том, что в ней есть одна строка, имеет имя, означающее «две».
Ключ - «покажи мне все возможные комбинации». Я использовал их вместе с другими вычисляемыми полями и затем отсортировал / отфильтровал их.
Например, предположим, что вы создаете приложение для арбитража (торговли). У вас есть продавцы, предлагающие товары по цене, а покупатели просят товары по цене. Вы выполняете перекрестное соединение по ключу продукта (чтобы сопоставить потенциальных покупателей и продавцов), вычисляете разницу между стоимостью и ценой, затем сортируете по убыванию. чтобы дать вам (посреднику) наиболее прибыльные сделки для исполнения. Конечно, почти всегда у вас будут другие критерии ограничивающего фильтра.
Принимает что-то вроде таблицы цифр, в которой десять строк для цифр 0–9. Вы можете использовать перекрестное соединение для этой таблицы несколько раз, чтобы получить результат, который содержит необходимое вам количество строк с соответствующими номерами результатов. Это имеет ряд применений. Например, вы можете объединить его с функцией datadd (), чтобы получить набор для каждого дня в заданном году.
Это интересный способ использования перекрестного соединения для создания отчета с перекрестной таблицей . Я нашел его в SQL For Smarties Джо Селко и использовал его несколько раз. Это требует небольшой настройки, но стоит потраченного времени.
Представьте, что у вас есть серия запросов, которые вы хотите задать по определенной комбинации товаров и дат (цены, наличие и т. Д.). Вы можете загружать элементы и даты в отдельные временные таблицы, а ваши запросы перекрестно объединять таблицы. Это может быть более удобным, чем альтернатива перечисления элементов и дат в предложениях IN, тем более что некоторые базы данных ограничивают количество элементов в предложении IN.
вы можете использовать его 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;