2016-05-27 57 views
0

我有三個表,t1,t2和t3。表結構和值:CROSS JOIN超過兩個表

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 

因此,與普通的SQL我可以加入t1和t2上t1_k1 = t2_k1和T2和T3上t2_k2 = t3_k2,那就是:

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

要獲得

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

現在我試圖用bigQuery SQL得到相同的結果。從我的理解,使用CROSS JOIN應該工作就像普通的SQL逗號,所以我想下面將工作:

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 

但我得到一個錯誤,「場‘t3_k2’上的任何一方未找到加入」。 添加括號這樣的:

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 

給出了一個(相當坦率隱蔽)的語法錯誤「遇到‘’在線0,列0」。 只有兩個表CROSS JOIN可以工作,但與正常的JOIN沒有區別。 我還沒有發現在兩個以上的表上使用CROSS JOIN的例子。可能嗎?難道我做錯了什麼?

回答

4

嘗試以下

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 

注:我認爲你的例子只是針對解決您的CROSS JOIN的問題 - 但想提一提,如果你的榜樣真正代表您的問題 - 你不需要CROSS JOIN - 而你需要[INNER] JOIN,如下

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 

對於第二個查詢增加可運行的例子 - 來證明它的工作原理: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

你的第二個例子不起作用。我編輯它來閱讀「選擇t1_val,t2_val,t3_val從...」,我得到:「字段't3_val'沒有找到任何一方的JOIN」。 – persson

+0

首先適合你嗎? –

+0

它可以工作,但它也可以與常規JOIN一起使用。那麼,CROSS JOIN有什麼意義? – persson

0

由於米哈伊爾在他的回答中注意到,你不需要CROSS JOIN,常規的JOIN工作正常。以下是如何做到這一點在一個聲明中,沒有多層次的連接:

我用內嵌SELECT語句,以提供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

謝謝。那麼什麼時候CROSS JOIN有用? – persson

+0

我不確定您的查詢是否正確。 – persson

+0

當您沒有表格之間的平等匹配時需要CROSS JOIN,但需要一些更復雜的條件。那麼你唯一的選擇就是用WHERE子句做CROSS JOIN。它可能會慢很多。如果可能,請使用常規JOIN。 什麼不適用於您的查詢?它在BQ UI中成功運行:)。 – Michael