Google BigQuery SQL:加入后防止列前缀重命名
Posted
技术标签:
【中文标题】Google BigQuery SQL:加入后防止列前缀重命名【英文标题】:Google BigQuery SQL: Prevent column prefix renaming after join 【发布时间】:2016-02-25 23:31:32 【问题描述】:假设您有一个表“table_with_100_columns”。
并且您想通过简单的连接再添加一列...而不更改所有列名。换句话说,你想写类似
SELECT a.* as <a's columns without prefix>, additional_field
FROM [table_with_100_columns] a
JOIN [table_with_2_columns] b
ON a.col1 = b.key
您应该能够这样做以生成一个包含 101 列的新表,而无需手动重命名每一列。现在我知道如何做到这一点的唯一方法如下:
SELECT
a.col1 as col1,
a.col2 as col2,
a.col3 as col3,
...
a.col100 as col100,
b.additional_field as additional_field
FROM [table_with_100_columns] a
JOIN [table_with_2_columns] b
ON a.col1 = b.key
必须编写 100 行不必要的代码来向表中再添加一列,效率低得令人难以置信 - 所以我希望在加入时有更好的方法来保留列名?
更新
这在 BigQuery 中似乎还不可能。它很容易实现,我向 Google BigQuery 团队提出以下建议:
if no fields share a name in SELECT clause:
if no subtable reference names given:
Do not rename fields after JOIN
这不会破坏任何当前的功能,并为一个非常有用的功能添加了简单的支持。
【问题讨论】:
你试过用 python 或类似的东西生成 SQL 代码吗? 当然可以,但是这样做通常需要先使用辅助辅助查询来获取所有列名,然后提取列,然后每次生成 SQL。由客户端用户处理是一件奇怪的事情。这也使得代码非常冗长,并且 30k 字符截断不允许在查询描述中超过 3 或 4 个连接。它包含一个如此简单的功能 - 特别是如果表在列中有列 - 我认为有一种方法可以使用 Google BigQuery 来实现。 【参考方案1】:我认为这个问题是 BigQuery Legacy SQL 特有的。 如果您将使用 Big Standard SQL - 您将不会遇到此问题 - 请参见下面的示例
#standardSQL
WITH table_with_100_columns AS (
SELECT 11 AS col1, 21 AS col2, 31 AS col3 UNION ALL
SELECT 12 AS col1, 22 AS col2, 32 AS col3 UNION ALL
SELECT 13 AS col1, 23 AS col2, 33 AS col3 UNION ALL
SELECT 14 AS col1, 24 AS col2, 34 AS col3 UNION ALL
SELECT 15 AS col1, 25 AS col2, 35 AS col3
),
table_with_2_columns AS (
SELECT 11 AS key, 17 AS additional_field UNION ALL
SELECT 12 AS key, 27 AS additional_field UNION ALL
SELECT 13 AS key, 37 AS additional_field UNION ALL
SELECT 14 AS key, 47 AS additional_field UNION ALL
SELECT 15 AS key, 57 AS additional_field
)
SELECT a.*, additional_field
FROM `table_with_100_columns` AS a
JOIN `table_with_2_columns` AS b
ON a.col1 = b.key
如果您需要将查询的其余部分重写为标准 SQL,请参阅 Migrating from legacy SQL
输出将如下所示,带有原始列名(无前缀)
col1 col2 col3 additional_field
13 23 33 37
11 21 31 17
15 25 35 57
12 22 32 27
14 24 34 47
【讨论】:
【参考方案2】:我不知道这里有什么可用的选项,而不是让那些 100 unnecessary lines
成为代码的一部分。
因此,对于您的特定用例,您可以使用 how to actually make it in most optimal way
我认为可能很多,但我在下面看到最明显的两个——它们更不重要,但为了我的答案的完整性,我把它放在这里:
选项 1——一次性行动/需要
只需将以下语句的输出输入到任何电子表格中,将其转置并修饰为预期的 SQL(至少在您的问题的第二个查询中,它在 SELECT 和 FROM 之间的部分)
SELECT * FROM table_with_100_columnsoutput WHERE false
换句话说,您可以使用任何最友好的办公工具手动完成此操作
选项 2 - 您需要此功能的频率较低或作为某个流程的一部分
通过使用Tables:get API 检索架构并查找schema.fields[],使用您选择的任何language/client 生成SQL 代码
在 sql 代码组装后 - 你使用API of your choice执行它
可以是 get
或 insert
或任何适合您的实现逻辑的东西
选项 3 - BigQuery Mate“添加字段”按钮
第 1 步 - 在导航栏中选择表格,以便您可以在内容面板中查看表格的架构 第 2 步 - 在查询编辑器中将光标设置在需要插入字段的位置 第 3 步 - 点击“添加字段”按钮
已部署选项 3,支持别名使用。现在在网上商店有售
【讨论】:
嗨米哈伊尔 - 我很感激你的回答!但是,您的回答并没有为发布的问题提供合理的解决方案(请参阅我上面关于使用客户端程序生成 sql 的缺点的评论 - 即它不能普遍并且需要大量工作并且仍然产生非常在描述中被截断的长 sql 查询)。看起来根本没有解决办法。 明白了。提供我的答案时,我只是没有看到您的 cmets 检查选项 3。这在 BQ Mate 中还没有,但假设它是 - BQ UI 中的这种类型的功能对您的情况有帮助吗? 漂亮的样机。但是,我觉得这应该在不添加 UI 的情况下处理。我提出了一个不同的解决方案。相反,只需检查 -> 如果 SELECT 子句中没有同名字段,则无需给子表引用名称,在这种情况下,不会发生重命名。 同意并希望,谷歌团队会做这样的事情。同时,我正在为 bq mate 部署一些附加功能以在 ui 中支持这一点。将于今天晚些时候在 chrome 网上商店中提供【参考方案3】:目前最简单的解决方案是使用标准 SQL,它不会为任何连接表所独有的任何字段添加前缀。
【讨论】:
您应该详细说明您的答案、示例代码等【参考方案4】:从 Cloud SDK 的 127.0.0(2016-09-21) 版本开始,新的标准 SQL 查询参数包括 FULL [OUTER] JOIN 功能,作为 Cloud BigQuery 的一部分。事实上,调用FULL OUTER JOIN
(或简称FULL JOIN
)会返回from_items
中满足连接条件的所有行的所有字段。
因此,只要在查询中指定FULL JOIN
,在标准 SQL 中运行查询将使您能够向预先存在的表添加另一列(无需重命名)。有关如何启用标准 SQL 以与 BigQuery 语句一起使用的详细信息,请参阅启用标准 SQL reference。
【讨论】:
【参考方案5】:因为我需要坚持使用 Legacy SQL(因为我与另一个使用 Legacy SQL 的系统集成并且由于列前缀而崩溃)
我设法通过替换 SQL 的选择部分来解决问题
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON [some_condition]
GROUP BY [group_columns]
到
SELECT
column1 as new_name1,
column2 as new_name2,
column3 as new_name3
FROM table1 t1
LEFT JOIN table2 t2
ON [some_condition]
GROUP BY [group_columns]
现在 column1 将显示为 new_name1 而不是 t1_column1
【讨论】:
以上是关于Google BigQuery SQL:加入后防止列前缀重命名的主要内容,如果未能解决你的问题,请参考以下文章