[英]CROSS JOIN more than two tables
我有三个表,t1、t2 和 t3。 表结构和值:
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_k1 = t2_k1 上加入 t1 和 t2,在 t2_k2 = t3_k2 上加入 t2 和 t3,即:
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
但我收到一个错误,“在 JOIN 的任何一侧都找不到字段 '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 的示例。 可能吗? 难道我做错了什么?
试试下面
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
正如Mikhail在他的回答中注意到的那样,您不需要CROSS JOIN,常规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
所以事实证明,这完全是定义表别名的问题,请参见另一个问题的示例: CROSS JOIN:只有两个表? 。
也许它在过去 6 年发生了变化,但现在使用逗号作为 CROSS JOIN 作品,你只需要小心歧义。
SELECT
t1_val,
t2_val,
t3_val
FROM (
SELECT * FROM
(SELECT 1 AS t1_id, 'k1foo' AS t1_k1, 't1foo' AS t1_val) UNION ALL
(SELECT 2 AS t1_id, 'k1bar' AS t1_k1, 't1bar' AS t1_val) UNION ALL
(SELECT 3 AS t1_id, 'k1baz' AS t1_k1, 't1baz' AS t1_val)
) AS a
,(
SELECT * FROM
(SELECT 1 AS t2_id, 'k1foo' AS t2_k1, 'k2foo' AS t2_k2, 't2foo' AS t2_val) UNION ALL
(SELECT 2 AS t2_id, 'k1bar' AS t2_k1, 'k2bar' AS t2_k2, 't2bar' AS t2_val) UNION ALL
(SELECT 3 AS t2_id, 'k1baz' AS t2_k1, 'k2baz' AS t2_k2, 't2baz' AS t2_val)
) AS b
,(
SELECT * FROM
(SELECT 1 AS t3_id, 'k2foo' AS t3_k2, 't3foo' AS t3_val) UNION ALL
(SELECT 2 AS t3_id, 'k2bar' AS t3_k2, 't3bar' AS t3_val) UNION ALL
(SELECT 3 AS t3_id, 'k2baz' AS t3_k2, 't3baz' AS t3_val)
) AS c
where
a.t1_k1 = b.t2_k1
AND b.t2_k2 = c.t3_k2
上面的查询结果:
t1foo | t2foo | t3foo
t1bar | t2bar | t3bar
t1baz | t2baz | t3baz
您可以复制并粘贴以检查。
但是,是的,在这个具体的例子中,正如 Michael 和 Mikhail 指出的那样,使用 INNER JOIN 会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.