Eine Kreuzverbindung führt ein kartesisches Produkt für die Tupel der beiden Sätze aus.
SELECT *
FROM Table1
CROSS JOIN Table2
Welche Umstände machen eine solche SQL-Operation besonders nützlich?
Eine Kreuzverbindung führt ein kartesisches Produkt für die Tupel der beiden Sätze aus.
SELECT *
FROM Table1
CROSS JOIN Table2
Welche Umstände machen eine solche SQL-Operation besonders nützlich?
Antworten:
Wenn Sie ein "Raster" haben, das Sie vollständig ausfüllen möchten, z. B. Größen- und Farbinformationen für ein bestimmtes Kleidungsstück:
select
size,
color
from
sizes CROSS JOIN colors
Möglicherweise möchten Sie eine Tabelle, die für jede Minute des Tages eine Zeile enthält, und Sie möchten damit überprüfen, ob jede Minute eine Prozedur ausgeführt wurde, sodass Sie möglicherweise drei Tabellen kreuzen:
select
hour,
minute
from
hours CROSS JOIN minutes
Oder Sie haben eine Reihe von Standardberichtsspezifikationen, die Sie jeden Monat im Jahr anwenden möchten:
select
specId,
month
from
reports CROSS JOIN months
Das Problem bei der Beibehaltung dieser Ansichten besteht darin, dass Sie in den meisten Fällen kein vollständiges Produkt wünschen, insbesondere in Bezug auf Kleidung. Sie können MINUS
der Abfrage Logik hinzufügen , um bestimmte Kombinationen zu entfernen, die Sie nicht tragen. Möglicherweise ist es jedoch einfacher, eine Tabelle auf andere Weise zu füllen und kein kartesisches Produkt zu verwenden.
Möglicherweise versuchen Sie auch den Cross-Join für Tabellen, die möglicherweise einige Zeilen mehr enthalten als gedacht, oder Ihre WHERE
Klausel fehlte teilweise oder vollständig. In diesem Fall benachrichtigt Sie Ihr DBA umgehend über die Auslassung. Normalerweise wird er oder sie nicht glücklich sein.
Generieren Sie Daten zum Testen.
Normalerweise benötigen Sie für die meisten Datenbankabfragen kein vollständiges kartesisches Produkt. Die ganze Kraft relationaler Datenbanken besteht darin, dass Sie alle Einschränkungen anwenden können, an denen Sie interessiert sein könnten, um zu vermeiden, dass unnötige Zeilen aus der Datenbank gezogen werden.
Ich nehme an, ein erfundenes Beispiel, bei dem Sie dies wünschen könnten, ist, wenn Sie eine Tabelle mit Mitarbeitern und eine Tabelle mit Jobs haben, die erledigt werden müssen, und alle möglichen Zuordnungen eines Mitarbeiters zu einem Job anzeigen möchten.
Ok, das wird die Frage wahrscheinlich nicht beantworten, aber wenn es wahr ist (und ich bin mir nicht einmal sicher), ist es ein lustiges Stück Geschichte.
In den frühen Tagen von Oracle erkannte einer der Entwickler, dass er jede Zeile in einer Tabelle duplizieren musste (es ist beispielsweise möglich, dass es sich um eine Ereignistabelle handelte, und dass er sie getrennt zwischen "Startereignis" und "Endereignis" ändern musste. Einträge). Er erkannte, dass er, wenn er eine Tabelle mit nur zwei Zeilen hatte, eine Kreuzverknüpfung durchführen konnte, indem er nur die Spalten in der ersten Tabelle auswählte und genau das bekam, was er brauchte. Also schuf er einen einfachen Tisch, den er natürlich "DUAL" nannte.
Später muss er etwas tun, was nur über eine Auswahl aus einer Tabelle möglich ist, obwohl die Aktion selbst nichts mit der Tabelle zu tun hat (vielleicht hat er seine Uhr vergessen und wollte die Zeit über SELECT SYSDATE FROM lesen. .) Er erkannte, dass er immer noch seinen DUAL-Tisch herumliegen hatte und benutzte ihn. Nach einer Weile hatte er es satt, die Zeit zweimal gedruckt zu sehen, und löschte schließlich eine der Zeilen.
Andere bei Oracle begannen, seine Tabelle zu verwenden, und schließlich wurde beschlossen, sie in die Standardinstallation von Oracle aufzunehmen.
Dies erklärt, warum eine Tabelle, deren einzige Bedeutung darin besteht, dass sie eine Zeile enthält, einen Namen hat, der "zwei" bedeutet.
Der Schlüssel ist "Zeig mir alle möglichen Kombinationen". Ich habe diese in Verbindung mit anderen berechneten Feldern verwendet und diese dann sortiert / gefiltert.
Angenommen, Sie erstellen eine Arbitrage-Anwendung (Handelsanwendung). Sie haben Verkäufer, die Produkte zu einem Preis anbieten, und Käufer, die nach Produkten zu einem Preis fragen. Sie führen einen Cross-Join für den Produktschlüssel durch (um die potenziellen Käufer und Verkäufer abzugleichen), berechnen die Spanne zwischen Kosten und Preis und sortieren dann absteigend. um Ihnen (dem Mittelsmann) die profitabelsten Trades zu bieten, die Sie ausführen können. Fast immer haben Sie natürlich andere Begrenzungsfilterkriterien.
Nimmt so etwas wie eine Ziffern-Tabelle, die zehn Zeilen für die Ziffern 0-9 enthält. Sie können Cross Join für diese Tabelle einige Male verwenden, um ein Ergebnis zu erhalten, das so viele Zeilen enthält, wie Sie benötigen, wobei die Ergebnisse entsprechend nummeriert sind. Dies hat eine Reihe von Verwendungsmöglichkeiten. Sie können es beispielsweise mit einer Funktion datadd () kombinieren, um einen Satz für jeden Tag in einem bestimmten Jahr zu erhalten.
Dies ist eine interessante Möglichkeit, einen Cross-Join zum Erstellen eines Kreuztabellenberichts zu verwenden . Ich habe es in Joe Celkos SQL For Smarties gefunden und es mehrmals verwendet. Es dauert zwar ein wenig, ist aber die investierte Zeit wert.
Stellen Sie sich vor, Sie hatten eine Reihe von Anfragen, die Sie über eine bestimmte Kombination von Artikeln und Daten (Preise, Verfügbarkeit usw.) stellen möchten. Sie können die Elemente und Daten in separate temporäre Tabellen laden und Ihre Abfragen mit den Tabellen verknüpfen. Dies ist möglicherweise praktischer als die Alternative, die Elemente und Daten in IN-Klauseln aufzulisten, insbesondere da einige Datenbanken die Anzahl der Elemente in einer IN-Klausel begrenzen.
Sie können es CROSS JOIN verwenden, um: - Daten zu Testzwecken zu generieren - alle Eigenschaften zu kombinieren - Sie benötigen alle möglichen Kombinationen von z. B. Blutgruppen (A, B, ..) mit Rh - / + usw. - - stimmen Sie es ab für deine Zwecke;) - Ich bin kein Experte auf diesem Gebiet;)
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;