Was sind die Verwendungszwecke für Cross Join?


105

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?


36
Es ist wirklich traurig, dass diese Frage geschlossen wurde. Ich denke, es könnte als Community-Wiki markiert werden, aber zu sagen, dass es nicht konstruktiv ist, ist unfair.
Wayne Koorts

1
Genau. Dies beantwortete genau die Frage, die ich hatte.
Hades

10
Es gibt Zeiten, in denen ein neuerer Entwickler Probleme hat, die Auswirkungen bestimmter Funktionen der von ihm verwendeten Software zu verstehen. Fragen wie diese sind insbesondere für neuere Entwickler hilfreich, vor allem, weil die folgende Diskussion viele Möglichkeiten beleuchtet, die der Junior-Entwickler nie in Betracht gezogen hat. Das Format der Frage ist bestenfalls elementar, aber die Absicht scheint ehrlich zu sein, indem sie fragt: "Warum gibt es das überhaupt?" Ich stimme Wayne Koorts zu, es ist eine Schande, dass casperOne beschlossen hat, dies zu schließen und es "nicht konstruktiv" nannte. Der "nicht konstruktive" Teil ärgert mich besonders.
Kaorie

Antworten:


93

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 MINUSder 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 WHEREKlausel 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.


5
... In diesem Fall benachrichtigt Sie Ihr DBA umgehend über die Auslassung. Normalerweise wird er oder sie nicht glücklich sein. ... haha, so wahr!
RSW

2
@ Dave: Wird das zweite Beispiel nicht nur eine Stunde CROSS JOIN Minuten sein?
Rakesh

@ Rakesh, guter Fang, ich dachte an etwas anderes als das, was ich tippte. Fest.
Dave DuPlantis

1
Ich kann mir vorstellen, dass ein Cross-Join sehr praktisch ist, wenn Sie zwei Sätze von IDs (möglicherweise im CSV-Format) erhalten, wobei ein Satz die Mitarbeiter-IDs und der andere Aufgaben-IDs enthält. Die Idee ist, dass Sie eine M2M-Tabelle für EmployeeTask haben. Sie können den Cross-Join verwenden, um jedem Mitarbeiter jede bestimmte Aufgabe zuzuweisen, vorausgesetzt, Sie haben die CSV in Tabellenvariablen (oder etwas anderes) umgewandelt.
SynBiotik


14

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.


11

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.


8

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.


Ah! Diese Erklärung ist für mich am sinnvollsten. In diesem Fall macht ein INNER JOIN keinen Sinn, da keine Beziehung zwischen einer Produkt-ID und einem Verkäufer besteht, da mehrere Verkäufer dasselbe Produkt verkaufen können.
Moonman239

3

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.



1

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.


1

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;
  • Erstellen Sie einen Join für 2 Tabellen ohne gemeinsame ID und gruppieren Sie ihn dann mit max () usw., um die höchstmögliche Kombination zu finden
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.