Які корисні можливості для Cross Join?


105

Хрестовий з'єднання виконує декартовий виріб на кортежах двох комплектів.

SELECT *
FROM Table1
CROSS JOIN Table2

Які обставини роблять таку операцію SQL особливо корисною?


36
Дуже сумно, що це питання було закрито. Я думаю, що це може бути позначено спільнотою Wiki, але сказати, що це не конструктивно, несправедливо.
Уейн Коортс

1
Я згоден. Це відповіло на точне запитання, яке у мене було.
Гадес

10
Бувають випадки, коли у нового розробника виникають проблеми з розумінням наслідків певних функцій програмного забезпечення, яке вони використовують. Такі питання - це особливість, корисна для нових розробників, насамперед тому, що наступна дискусія висвітлює багато можливостей, які молодший розробник ніколи не розглядав. Формат питання є елементарним, у кращому випадку, але намір, здається, є чесним, оскільки він запитує "чому це взагалі існує?" Я погоджуюся з Уейн Коортсом, прикро, що casperOne обрав це закрити і назвав це "неконструктивним". Особливо мене дратує "не конструктивна" частина.
Каорі

Відповіді:


93

Якщо у вас є "сітка", яку ви хочете заповнити повністю, як інформація про розмір та колір для певного одягу:

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пункт частково або повністю відсутній. У такому випадку ваша DBA негайно повідомить вас про упущення. Зазвичай він чи вона не будуть щасливі.


5
... У такому випадку ваша DBA негайно повідомить вас про упущення. Зазвичай він чи вона не будуть щасливі. ... ха-ха, так правда!
RSW

2
@Dave: Не хочете, щоб другим прикладом було лише годину CROSS JOIN хвилин?
Ракеш

@ Ракеш, хороший улов, я думав про щось інше, ніж те, що я набирав. Виправлено.
Дейв ДуПлантіс

1
Я можу уявити, що перехресне з'єднання є дуже практичним, якби вам дали два набори ідентифікаторів (можливо, у форматі csv), один набір містив би ідентифікатори службовця, а інший містив б ідентифікатори завдань. Ідея полягає в тому, що у вас є таблиця M2M для EmployeeTask. Ви можете використовувати перехресне з'єднання, щоб призначити кожне задане кожному працівнику, якщо ви трансформували файл csv в таблиці змінних (або щось таке).
SynBiotik


14

Зазвичай для більшості запитів до бази даних зазвичай не потрібно повноцінного декартового продукту. Вся потужність реляційних баз даних полягає в тому, що ви можете застосовувати будь-які обмеження, які можуть вас зацікавити, щоб уникнути витягування непотрібних рядків з db.

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


11

Гаразд, це, мабуть, не дасть відповіді на питання, але, якщо це правда (і я навіть не впевнений у цьому), це кумедна історія.

У перші дні Oracle один з розробників зрозумів, що йому потрібно дублювати кожен рядок у таблиці (наприклад, можливо, це таблиця подій, і йому потрібно змінити її окремими "стартовою подією" та "кінцевою подією" записи). Він зрозумів, що якби у нього була таблиця з лише двома рядами, він може зробити хрестоподібне з'єднання, вибравши лише стовпці в першій таблиці і отримати саме те, що йому потрібно. Тому він створив просту таблицю, яку він, природно, досить назвав "ДУАЛЬНО".

Пізніше йому потрібно зробити щось, що можна було зробити лише за допомогою вибору з таблиці, навіть якщо сама дія не мала нічого спільного з таблицею (можливо, він забув годинник і хотів прочитати час через ВИБІР СИСТАТУ ВІД. .) Він зрозумів, що у нього все ще лежить свій ДУАЛЬНИЙ стіл, і користувався цим. Через деякий час він втомився бачити час, надрукований двічі, тож він, можливо, видалив один із рядків.

Інші в Oracle почали використовувати його стіл, і врешті-решт було вирішено включити його до стандартної установки Oracle.

Що пояснює, чому таблиця, єдине значення якої полягає в тому, що вона має один рядок, має ім’я, що означає "два".


8

Ключ - "покажи мені всі можливі комбінації". Я використовував їх спільно з іншими розрахованими полями, а потім їх сортував / фільтрував.

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


Ах! Це пояснення має для мене найбільш сенс. У цьому випадку ВНУТРІШНЯ ПРИЄДНАННЯ немає сенсу, оскільки немає ідентифікатора між ідентифікатором товару та продавцем, оскільки кілька продавців можуть продавати один і той же товар.
moonman239

3

Бере щось подібне до таблиці цифр, у якій десять рядків для цифр 0-9. Ви можете використовувати перехресне з'єднання на цій таблиці кілька разів, щоб отримати результат, який має скільки завгодно рядків, при цьому результати будуть пронумеровані відповідним чином. Це має ряд застосувань. Наприклад, ви можете комбінувати його з функцією datadd (), щоб отримати набір на кожен день у даному році.



1

Уявіть, у вас була серія запитів, які ви хочете задати щодо певної комбінації елементів та дат (ціни, доступність тощо). Ви можете завантажити елементи та дати в окремі тимчасові таблиці, а ваші запити перехресно приєднатись до таблиць. Це може бути зручніше, ніж альтернатива перерахування елементів та дат у пунктах IN, тим більше, що деякі бази даних обмежують кількість елементів у пункті IN.


1

Ви можете використовувати його CROSS JOIN для: - отримання даних для цілей тестування - об'єднати всі властивості - потрібно всі можливі поєднання наприклад , групи крові (A, B, ..) з Rh - / +, і т.д. ... --tune його для ваших цілей;) - я не експерт у цій галузі;)

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 () тощо), щоб знайти максимально можливу комбінацію
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.