Database
 sql >> Datenbank >  >> RDS >> Database

Ihr ultimativer Leitfaden für SQL Join:CROSS JOIN – Teil 3

CROSS JOIN steht im Rampenlicht. Dieser Artikel schließt unsere kleine Reihe von Veröffentlichungen zu SQL JOIN ab. Wenn Sie die beiden vorherigen Artikel verpasst haben, schlagen Sie wie folgt darauf zurück:

  • Ihr ultimativer Leitfaden für SQL Join – Teil 1:INNER JOIN
  • Ihr ultimativer Leitfaden für SQL Join – Teil 2:OUTER JOIN

SQL Server CROSS JOIN ist der einfachste aller Joins. Es implementiert eine Kombination von 2 Tabellen ohne Join-Bedingung. Wenn Sie 5 Zeilen in einer Tabelle und 3 Zeilen in einer anderen haben, erhalten Sie 15 Kombinationen. Eine andere Definition ist ein kartesisches Produkt.

Warum sollten Sie nun Tabellen ohne Join-Bedingung kombinieren? Warten Sie ein bisschen, denn wir kommen dorthin. Lassen Sie uns zunächst auf die Syntax verweisen.

SQL CROSS JOIN-Syntax

Wie bei INNER JOIN können Sie einen CROSS JOIN aus 2 Standards, SQL-92 und SQL-89, haben. T-SQL unterstützt beide Syntaxen, aber ich bevorzuge SQL-92. Lesen Sie Teil 1, der INNER JOIN gewidmet ist, wenn Sie wissen möchten, warum.

SQL-92-Syntax

SELECT
 a.column1
,b.column2
FROM Table1 a
CROSS JOIN Table2 b

SQL-89

SELECT
 a.column1
,b.column2
FROM Table1 a, Table2 b 

Ähnlich wie SQL-89 – INNER JOIN ohne die Join-Bedingung.

5 Beispiele für die Verwendung von SQL Server CROSS JOIN

Sie fragen sich vielleicht, wann Sie SQL CROSS JOIN verwenden können. Natürlich ist es nützlich, um Wertkombinationen zu formen. Was noch?

1. Testdaten

Wenn Sie eine große Datenmenge benötigen, hilft Ihnen ein CROSS JOIN. Beispielsweise haben Sie eine Tabelle mit Anbietern und Produkten. Eine weitere Tabelle enthält Produkte, die der Anbieter anbietet. Wenn es leer ist und Sie schnell Daten benötigen, können Sie Folgendes tun:

SELECT
 P.ProductID
,v.BusinessEntityID AS VendorID
FROM 
Production.Product p
CROSS JOIN Purchasing.Vendor v 

Es generierte 52.416 Datensätze in meiner Kopie von AdventureWorks . Das reicht aus, um Apps und Leistung zu testen. Wenn Sie Ihre App jedoch Benutzern präsentieren, verwenden Sie Ihre Quelle anstelle dieser Daten aus unserem Beispiel.

2. Ergebnisse aus fehlenden Kombinationen abrufen

Im vorherigen Artikel haben wir die Verwendung des OUTER JOIN veranschaulicht, um Ergebnisse aus fehlenden Werten zu erhalten. Dieses Mal verwenden wir fehlende Kombinationen. Lassen Sie uns versuchen, die Produkte zu bekommen, bei denen Store 294 kein Geld verdient hat.

-- get store 294 ('Professional Sales and Service') list of products without sales orders for January 2014
SELECT DISTINCT
 b.Name AS Product
FROM Sales.Store a
CROSS JOIN Production.Product b
LEFT JOIN (SELECT
	     c.StoreID
	    ,a.ProductID
	    ,SUM(a.LineTotal) AS OrderTotal
	    FROM Sales.SalesOrderDetail a
	    INNER JOIN Sales.SalesOrderHeader b ON a.SalesOrderID = b.SalesOrderID
	    INNER JOIN Sales.Customer c ON b.CustomerID = c.CustomerID
	    WHERE c.StoreID = 294 AND
		   b.OrderDate BETWEEN '01/01/2014' AND '01/31/2014'
	    GROUP BY c.StoreID, a.ProductID) d ON a.BusinessEntityID = d.StoreID 
		                                AND b.ProductID = d.ProductID
WHERE d.OrderTotal IS NULL
AND a.BusinessEntityID = 294
ORDER BY b.Name 

Wie Sie sehen, benötigen wir zunächst alle Produkt- und Filialkombinationen – wir verwenden einen CROSS JOIN. Dann benötigen wir eine Liste der verkauften Produkte für den Zeitraum Januar 2014. Wenden Sie schließlich LEFT JOIN auf diese Liste an und verwenden Sie die WHERE-Klausel, um nur die Produkte ohne Verkäufe zu erhalten. Dann erhalten wir Informationen über Produkte, die nicht verkauft wurden.

3. Wörter aus Buchstabenkombinationen bilden

Wenn Sie auf Wortspiele mit Buchstabenkombinationen stehen, können Sie CROSS JOIN mit einem Self-Join verwenden. Hier ist ein Beispiel mit den drei Buchstaben „D“, „O“ und „G“.


DECLARE @table TABLE(letter CHAR(1) NOT NULL)

INSERT INTO @table
VALUES ('D'),('O'),('G')

SELECT
 a.letter
,b.letter
,c.letter
FROM @table a
CROSS JOIN @table b
CROSS JOIN @table c
WHERE a.letter + b.letter + c.letter LIKE '%O%'

Ein ähnlicher Code ohne die WHERE-Klausel generiert 27 Datensätze. Die obige WHERE-Klausel hat dazu beigetragen, Kombinationen aus 3 ähnlichen Buchstabenkombinationen wie „DDD“ oder „GGG“ zu eliminieren. Unten ist das Ergebnis.

Da ich natürlich nicht viel Intelligenz in die Abfrage gesteckt habe, sind die meisten Ergebnisse keine Wörter. Trotzdem hilft es beim Denkteil des Spiels.

4. Essensvorschläge

Wir alle lieben Essen, aber es kann schwierig sein, die richtigen Kombinationen zu wählen. Wie in den vorherigen Beispielkonzepten erhalten Sie hier mögliche Essenskombinationen:


DECLARE @FoodMenu TABLE(FoodItem VARCHAR(50) NOT NULL, ItemType CHAR(1) NOT NULL)

-- main course
INSERT INTO @FoodMenu
VALUES
('Spaghetti with Meatballs','M'),
('Spaghetti with Fried Chicken','M'),
('Rice with Roasted Chicken','M')

-- side dish
INSERT INTO @FoodMenu
VALUES
('Buttered Corn and Carrots','S'),
('French Fries','S'),
('Vegetable Coleslaw','S')

-- drinks
INSERT INTO @FoodMenu
VALUES
('Orange Juice','D'),
('Pineapple Juice','D'),
('Soda','D')

SELECT
 a.FoodItem AS MainCourse
,b.FoodItem AS SideDish
,c.FoodItem AS Drinks
FROM @FoodMenu a
CROSS JOIN @FoodMenu b
CROSS JOIN @FoodMenu c
WHERE a.ItemType = 'M' AND
b.ItemType = 'S' AND
c.ItemType = 'D' 

Das Ergebnis:

Einige davon sind wünschenswert. Manche sagen:„Vergiss es!“ Das hängt von deinem Geschmack ab.

5. Auswahl an T-Shirt-Designs

Eine weitere mögliche Verwendung von CROSS JOIN ist das Erhalten von Designkombinationen für Hemden. Hier ist ein Beispielcode:


DECLARE @tshirts TABLE(attributeType CHAR(1) NOT NULL, Attribute VARCHAR(15))

--size
INSERT INTO @tshirts
VALUES
('S','Small'),
('S','Medium'),
('S','Large')

--color
INSERT INTO @tshirts
VALUES
('C','Red'),
('C','Blue'),
('C','Green'),
('C','Black'),
('C','Purple'),
('C','Yellow'),
('C','White')

--design
INSERT INTO @tshirts
VALUES
('D','Plain'),
('D','Printed')

SELECT
 a.Attribute AS Size
,b.Attribute AS Color
,c.Attribute AS Design
FROM @tshirts a
CROSS JOIN @tshirts b
CROSS JOIN @tshirts c
WHERE a.attributeType = 'S' AND
b.attributeType = 'C' AND 
c.attributeType = 'D'

Und die Ergebnisse? Schauen Sie sich seinen Teil in Abbildung 3 an:

Fallen Ihnen weitere Beispiele ein?

SQL Server CROSS JOIN-Leistung

Was ist der Haken bei der Verwendung von CROSS JOIN? Für das, was es wert ist, kann CROSS JOIN Leistungsprobleme verursachen, wenn Sie nicht aufpassen. Der gruseligste Teil ist, dass es ein Produkt aus 2 Sätzen bildet. Somit ergibt sich ohne Einschränkung eine WHERE-Klausel, Table1 mit 1000 Datensätzen CROSS JOIN mit Table2 aus 1.000.000 Datensätzen werden 1.000.000.000 Datensätze. Folglich sind das viele Seiten, die von SQL Server gelesen werden müssen.

Betrachten Sie als Beispiel die Paarung männlicher und weiblicher Mitarbeiter in AdventureWorks .

USE AdventureWorks
GO

SELECT
 P.LastName + ISNULL(' ' + p.Suffix,'') + ', ' + P.FirstName + ISNULL(' ' + P.MiddleName,'') AS Male
,P1.LastName + ISNULL(' ' + p1.Suffix,'') + ', ' + P1.FirstName + ISNULL(' ' + P1.MiddleName,'') AS Female
FROM HumanResources.Employee e
INNER JOIN Person.Person p ON e.BusinessEntityID = P.BusinessEntityID
CROSS JOIN HumanResources.Employee e1
INNER JOIN Person.Person p1 ON e1.BusinessEntityID = p1.BusinessEntityID
WHERE e.Gender = 'M'
AND e1.Gender = 'F' 

Der obige Code gibt Ihnen alle möglichen Paare von männlichen und weiblichen Mitarbeitern. Ich habe nur 17.304 Datensätze erhalten, aber sehen Sie sich die logischen Lesevorgänge in Abbildung 4 an:

Haben Sie die logischen Lesevorgänge der Person gesehen? Tisch? Das sind 53.268 x 8 KB Seiten! Ganz zu schweigen vom Arbeitstisch logische Lesevorgänge erfolgen in tempdb .

Die Schlussfolgerung? Überprüfen Sie das STATISTICS IO, und wenn es Sie stört, große logische Lesevorgänge zu sehen, formulieren Sie eine Abfrage anders. Zusätzliche Bedingungen in der WHERE-Klausel oder ein Teile-und-Herrsche-Ansatz können hilfreich sein.

Wenn ein CROSS JOIN zu einem INNER JOIN wird

Ja, das ist richtig. SQL Server kann einen CROSS JOIN als INNER JOIN verarbeiten. Wir haben bereits erwähnt, dass ein RIGHT JOIN, wenn er als LEFT JOIN verarbeitet wird, für CROSS JOIN gelten kann. Sehen Sie sich den folgenden Code an:

SELECT
 c.CustomerID
,c.AccountNumber
,P.BusinessEntityID
,P.LastName
,P.FirstName
FROM Sales.Customer c
CROSS JOIN Person.Person p
WHERE c.PersonID = P.BusinessEntityID 

Bevor wir uns den Ausführungsplan ansehen, sehen wir uns das INNER JOIN-Äquivalent an.

SELECT
 c.CustomerID
,c.AccountNumber
,P.BusinessEntityID
,P.LastName
,P.FirstName
FROM Sales.Customer c
INNER JOIN Person.Person p ON c.PersonID = P.BusinessEntityID 

Überprüfen Sie jetzt den Ausführungsplan unten.

Der oberste Plan ist die Abfrage mit einem CROSS JOIN. Der untere Plan ist die Abfrage, die einen INNER JOIN verwendet. Sie haben denselben QueryHashPlan .

Haben Sie das Hash Match bemerkt? Betreiber des Top-Plans? Es ist ein INNER JOIN. Aber wir haben einen CROSS JOIN im Code verwendet. Die WHERE-Klausel in der ersten Abfrage (WHERE c.PersonID =P.BusinessEntityID ) zwang die Ergebnisse, nur Kombinationen mit gleichen Schlüsseln zu haben. Logischerweise ist es also ein INNER JOIN.

Welches ist besser? Es ist Ihre persönliche Wahl. Ich bevorzuge INNER JOIN, weil die Absicht darin besteht, 2 Tabellen mit gleichen Schlüsseln zu verbinden. Die Verwendung von INNER JOIN macht es sehr deutlich. Aber das bin nur ich.

Schlussfolgerung

CROSS JOIN ist gut, um Ihnen alle möglichen Wertkombinationen zu geben. Sie wurden jedoch gewarnt, dass dies zu einer Art Datenexplosion führen kann. Verwenden Sie diesen JOIN mit Bedacht. Begrenzen Sie die Ergebnisse so weit wie möglich. Sie können auch einen CROSS JOIN schreiben, der funktional dem INNER JOIN entspricht.

Dieser Artikel beendet die Serie über SQL JOINs. Für zukünftige Referenzen können Sie diesen Artikel mit einem Lesezeichen versehen. Oder fügen Sie es Ihrer Sammlung in einem Browser hinzu.

Und vergessen Sie nicht, diesen Artikel in Ihren bevorzugten sozialen Medien zu teilen?