2016-05-27 29 views
0

Ich habe drei Tabellen, T1, T2 und T3. Tabellenstruktur und Werte:CROSS JOIN mehr als zwei Tabellen

t1_id | t1_k1 | t1_val 
------+-------+-------- 
1  | k1foo | t1foo 
2  | k1bar | t1bar 
3  | k1baz | t1baz 

t2_id | t2_k1 | t2_k2 | t2_val 
------+-------+-------+-------- 
1  | k1foo | k2foo | t2foo 
2  | k1bar | k2bar | t2bar 
3  | k1baz | k2baz | t2baz 

t3_id | t3_k2 | t3_val 
------+-------+-------- 
1  | k2foo | t3foo 
2  | k2bar | t3bar 
3  | k2baz | t3baz 

So mit normalen SQL I T1 und T2 auf t1_k1 = t2_k1 und T2 und T3 auf t2_k2 = t3_k2 verbinden kann, das heißt:

SELECT t1_val, t2_val, t3_val 
FROM t1, t2, t3 
WHERE t1_k1 = t2_k1 AND t2_k2 = t3_k2 

Um

t1foo | t2foo | t3foo 
t1bar | t2bar | t3bar 
t1baz | t2baz | t3baz 

Jetzt versuche ich das gleiche Ergebnis mit bigQuery SQL zu bekommen. Von meinem Verständnis, CROSS mit JOIN sollte wie das Komma in regelmäßigen SQL arbeiten, also dachte ich folgend funktionieren würde:

SELECT t1_val, t2_val, t3_val 
FROM test.t1 CROSS JOIN test.t2 CROSS JOIN test.t3 
WHERE t1_k1 = t2_k1 AND t2_k2 = t3_k2 

Aber ich erhalte eine Fehlermeldung, dass „Feld‚t3_k2‘nicht auf beiden Seiten der gefundenen BEITRETEN". Hinzufügen von Klammern wie folgt aus:

SELECT SELECT t1_val, t2_val, t3_val 
FROM ((test.t1 CROSS JOIN test.t2) CROSS JOIN test.t3) 
WHERE t1_k1 = t2_k1 AND t2_k2 = t3_k2 

eine gibt (offen ziemlich kryptisch) Syntaxfehler ‚Fand‚‘in Zeile 0, Spalte 0‘ Mit nur zwei Tabellen funktioniert CROSS JOIN, aber dann unterscheidet es sich nicht von einem normalen JOIN. Ich habe keine Beispiele gefunden, die CROSS JOIN an mehr als zwei Tabellen verwenden. Ist es möglich? Mache ich etwas falsch?

Antwort

4

Versuchen unter

SELECT t1_val, t2_val, t3_val 
FROM (
    SELECT t1_val, t2_val, t2_k2 
    FROM test.t1 AS a 
    CROSS JOIN test.t2 AS b 
    WHERE t1_k1 = t2_k1 
) AS c 
CROSS JOIN test.t3 AS d 
WHERE t2_k2 = t3_k2 

Anmerkung: Ich denke, dass Ihr Beispiel gerade ist zugeschnitten auf Ihre CROSS JOIN Problem zu beheben - aber ich wollte erwähnen, dass, wenn Ihr Beispiel wirklich Ihr Problem darstellt - Sie müssen nicht CROSS JOIN müssen - eher Sie müssen [INNER] JOIN, wie

SELECT t1_val, t2_val, t3_val 
FROM (
    SELECT t1_val, t2_val, t2_k2 
    FROM test.t1 AS a JOIN test.t2 AS b 
    ON t1_k1 = t2_k1 
) AS c 
JOIN test.t3 AS d ON t2_k2 = t3_k2 

Added runnable Beispiel für die zweite Abfrage unten - zu beweisen, dass es funktioniert: o)

SELECT t1_val, t2_val, t3_val 
FROM (
    SELECT t1_val, t2_val, t2_k2 
    FROM (
    SELECT * FROM 
    (SELECT 1 AS t1_id, 'k1foo' AS t1_k1, 't1foo' AS t1_val), 
    (SELECT 2 AS t1_id, 'k1bar' AS t1_k1, 't1bar' AS t1_val), 
    (SELECT 3 AS t1_id, 'k1baz' AS t1_k1, 't1baz' AS t1_val) 
) AS a 
    JOIN (
    SELECT * FROM 
    (SELECT 1 AS t2_id, 'k1foo' AS t2_k1, 'k2foo' AS t2_k2, 't2foo' AS t2_val), 
    (SELECT 2 AS t2_id, 'k1bar' AS t2_k1, 'k2bar' AS t2_k2, 't2bar' AS t2_val), 
    (SELECT 3 AS t2_id, 'k1baz' AS t2_k1, 'k2baz' AS t2_k2, 't2baz' AS t2_val) 
) AS b 
    ON t1_k1 = t2_k1 
) as c 
JOIN (
    SELECT * FROM 
    (SELECT 1 AS t3_id, 'k2foo' AS t3_k2, 't3foo' AS t3_val), 
    (SELECT 2 AS t3_id, 'k2bar' AS t3_k2, 't3bar' AS t3_val), 
    (SELECT 3 AS t3_id, 'k2baz' AS t3_k2, 't3baz' AS t3_val) 
) AS d 
ON t2_k2 = t3_k2 
+0

Ihr zweites Beispiel funktioniert nicht. Ich habe es bearbeitet, um "SELECT t1_val, t2_val, t3_val FROM ..." zu lesen, und ich bekomme: "Field 't3_val' nicht auf beiden Seiten des JOIN gefunden". – persson

+0

funktioniert zuerst für Sie? –

+0

Es funktioniert, aber es funktioniert auch mit regulären JOIN. Also, was ist der Sinn von CROSS JOINs? – persson

0

Wie Mikhail in seiner Antwort bemerkte, brauchen Sie CROSS JOIN nicht, reguläres JOIN funktioniert gut. Hier ist, wie es in einer Aussage zu machen, ohne Multi-Level-Joins:

I Inline-SELECT-Anweisungen verwendet, um Daten bereitzustellen, T1, T2, T3:

SELECT t1_val, t2_val, t3.t3_val as t3_val 
FROM (SELECT 1 as t1_id, "k1foo" as t1_k1, "t1foo" as t1_val) t1 
JOIN (SELECT 1 as t2_id, "k1foo" as t2_k1, "k2foo" as t2_k2, "t2foo" as t2_val) t2 
ON t1_k1 = t2_k1 
JOIN (SELECT 1 as t3_id, "k2foo" as t3_k2, "t3foo" as t3_val) t3 
ON t2_k2 = t3_k2 
+0

Danke. Wann ist CROSS JOIN nützlich? – persson

+0

Ich bin mir nicht sicher, ob Ihre Anfrage korrekt ist. – persson

+0

CROSS JOIN wird benötigt, wenn Sie keine Gleichheitsübereinstimmung zwischen Tabellen haben, aber stattdessen eine komplexere Bedingung haben. Dann ist Ihre einzige Option, CROSS JOIN mit WHERE-Klausel zu tun. Es könnte viel langsamer sein. Verwenden Sie nach Möglichkeit normale JOINs. Was funktioniert in dieser Abfrage nicht für Sie? Es läuft erfolgreich in BQ UI :). – Michael