Sprzężenie krzyżowe wykonuje iloczyn kartezjański na krotkach dwóch zbiorów.
SELECT *
FROM Table1
CROSS JOIN Table2
W jakich okolicznościach taka operacja SQL jest szczególnie użyteczna?
Sprzężenie krzyżowe wykonuje iloczyn kartezjański na krotkach dwóch zbiorów.
SELECT *
FROM Table1
CROSS JOIN Table2
W jakich okolicznościach taka operacja SQL jest szczególnie użyteczna?
Odpowiedzi:
Jeśli masz „siatkę”, którą chcesz wypełnić w całości, np. Informacje o rozmiarze i kolorze określonego elementu odzieży:
select
size,
color
from
sizes CROSS JOIN colors
Może potrzebujesz tabeli zawierającej wiersz dla każdej minuty w ciągu dnia i chcesz jej użyć do sprawdzenia, czy procedura wykonywała się co minutę, więc możesz skrzyżować trzy tabele:
select
hour,
minute
from
hours CROSS JOIN minutes
Lub masz zestaw standardowych specyfikacji raportów, które chcesz stosować w każdym miesiącu w roku:
select
specId,
month
from
reports CROSS JOIN months
Problem z utrzymaniem ich jako poglądów polega na tym, że w większości przypadków nie chcesz kompletnego produktu, szczególnie w odniesieniu do odzieży. Możesz dodać MINUS
logikę do zapytania, aby usunąć pewne kombinacje, których nie nosisz, ale może być łatwiej wypełnić tabelę w inny sposób i nie używać iloczynu kartezjańskiego.
Możesz również spróbować sprzężenia krzyżowego w tabelach, które mają być może kilka wierszy więcej niż myślisz, lub być może WHERE
brakuje Twojej klauzuli częściowo lub całkowicie. W takim przypadku Twój DBA powiadomi Cię niezwłocznie o zaniedbaniu. Zwykle nie będzie szczęśliwy.
Generuj dane do testów.
Zazwyczaj nie będziesz potrzebować pełnego produktu kartezjańskiego dla większości zapytań do baz danych. Cała siła relacyjnych baz danych polega na tym, że możesz zastosować dowolne ograniczenia, które mogą Cię zainteresować, aby uniknąć pobierania niepotrzebnych wierszy z bazy danych.
Przypuszczam, że jeden wymyślony przykład, w którym możesz chcieć, to sytuacja, gdy masz tabelę pracowników i tabelę prac, które wymagają wykonania i chcesz zobaczyć wszystkie możliwe przydziały jednego pracownika do jednej pracy.
Ok, to prawdopodobnie nie odpowie na pytanie, ale jeśli to prawda (a nie jestem tego nawet pewien), to fajna historia.
We wczesnych latach istnienia Oracle, jeden z programistów zdał sobie sprawę, że musi zduplikować każdy wiersz w tabeli (na przykład możliwe jest, że była to tabela zdarzeń i musiał ją zmienić osobno „zdarzenie początkowe” i „zdarzenie końcowe” wpisy). Uświadomił sobie, że gdyby miał tabelę z zaledwie dwoma wierszami, mógłby wykonać sprzężenie krzyżowe, wybierając tylko kolumny w pierwszej tabeli i uzyskać dokładnie to, czego potrzebuje. Stworzył więc prosty stół, który naturalnie nazwał „DUAL”.
Później musiał zrobić coś, co można było zrobić tylko poprzez wybór z tabeli, mimo że sama czynność nie miała nic wspólnego ze stołem (być może zapomniał o zegarku i chciał odczytać godzinę za pomocą opcji SELECT SYSDATE FROM ... .) Uświadomił sobie, że nadal ma swój stół DUAL leżący w pobliżu i użył tego. Po chwili miał dość podwójnego drukowania czasu, więc w końcu usunął jeden z wierszy.
Inni w Oracle zaczęli używać jego tabeli i ostatecznie zdecydowano się włączyć go do standardowej instalacji Oracle.
To wyjaśnia, dlaczego tabela, której jedynym znaczeniem jest to, że ma jeden wiersz, ma nazwę oznaczającą „dwa”.
Kluczem jest „pokaż mi wszystkie możliwe kombinacje”. Użyłem ich w połączeniu z innymi polami obliczeniowymi, a następnie posortowałem / przefiltrowałem je.
Załóżmy na przykład, że tworzysz aplikację arbitrażową (handlową). Masz sprzedawców oferujących produkty po określonej cenie, a kupujących proszących o produkty po określonej cenie. Wykonujesz sprzężenie krzyżowe w kluczu produktu (aby dopasować potencjalnych kupujących i sprzedających), obliczasz różnicę między kosztem a ceną, a następnie sortujesz malejąco. na tym, aby dać tobie (pośrednikowi) najbardziej dochodowe transakcje do wykonania. Prawie zawsze będziesz mieć oczywiście inne kryteria filtru ograniczającego.
Przyjmuje coś w rodzaju tabeli cyfr, która ma dziesięć wierszy na cyfry 0-9. Możesz użyć sprzężenia krzyżowego na tej tabeli kilka razy, aby uzyskać wynik, który ma dowolną liczbę potrzebnych wierszy, a wyniki są odpowiednio ponumerowane. Ma to wiele zastosowań. Na przykład możesz połączyć to z funkcją datadd (), aby uzyskać zestaw na każdy dzień w danym roku.
Jest to interesujący sposób użycia sprzężenia krzyżowego do utworzenia raportu tabeli przestawnej . Znalazłem go w SQL For Smarties Joe Celko i użyłem go kilka razy. To zajmuje trochę czasu, ale było warte zainwestowanego czasu.
Wyobraź sobie, że masz serię zapytań, które chcesz skierować do określonej kombinacji pozycji i dat (ceny, dostępność itp.). Możesz załadować elementy i daty do oddzielnych tabel tymczasowych, a zapytania krzyżować się z tabelami. Może to być wygodniejsze niż alternatywa polegająca na wyliczaniu pozycji i dat w klauzulach IN, zwłaszcza że niektóre bazy danych ograniczają liczbę elementów w klauzuli IN.
możesz go użyć CROSS JOIN do: - generowania danych do celów testowych - łączenia wszystkich właściwości - potrzebujesz wszystkich możliwych kombinacji np. grup krwi (A, B, ...) z Rh - / +, itd ... - strojenia do Twoich celów;) - nie jestem ekspertem w tej dziedzinie;)
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;