【问题标题】:Is there a way in Big query to execute dynamic queries something like 'EXEC' in sql server?大查询中有没有办法在 sql server 中执行诸如“EXEC”之类的动态查询?
【发布时间】:2019-08-26 12:58:33
【问题描述】:

我有一个包含 200 多个列名的表,这些列名是使用临时名称(如 - custColum1 -custColum200)创建的。

我有一个映射表,其中包含一个 custColum1-custColumn200 列表,它必须映射到该列表。例如

Table1(custColum1,custColum2) 
Mappingtable(tempColumnName,RealColumnName) 
data in mapping table be like 
(custColum1,Role_number)
(custColum2,Person_name)

我需要将表 1 更改为 Table1(Role_number,Person_name)。 注意:我无法使用此名称创建 table1,因为我不知道将映射哪一列。

在想我们是否可以做一些事情,比如创建一个动态查询并如下所示执行

SET @Sql = 'ALTER TABLE TABLE_NAME RENAME Column columnName'
           print  (@Sql)
           EXEC (@Sql)

有没有办法在 BigQuery 中做到这一点?任何想法都会很棒

【问题讨论】:

标签: dynamic google-bigquery user-defined-functions


【解决方案1】:

让我们假设简化示例如下

表1

映射表

我会手动处理您的用例的方式如下
首先,假设我们事先知道所有映射,我们可以手动组装所需的列表并使用它,如下所示

#standardSQL
CREATE OR REPLACE TABLE `project.dataset.Table1` AS 
SELECT NULL AS Role_number, NULL AS Person_name  -- this line to be generated
  FROM (SELECT 1) WHERE FALSE UNION ALL
SELECT * FROM `project.dataset.Table1`  

现在,我们需要“弄清楚”如何从上面的查询中生成下面的行

'SELECT NULL AS Role_number, NULL AS Person_name' 

这可以通过运行下面的查询来完成

#standardSQL
SELECT CONCAT('SELECT', STRING_AGG(CONCAT(' NULL AS ', RealColumnName) ORDER BY pos)) select_statement
FROM (
  SELECT TO_JSON_STRING(t) AS cols FROM `project.dataset.Table1` t LIMIT 1
), UNNEST(REGEXP_EXTRACT_ALL(cols, r'"(.*?)":')) col WITH OFFSET AS pos
LEFT JOIN `project.dataset.Mappingtable` ON tempColumnName = col  

这将产生我们需要的字符串

'SELECT NULL AS Role_number, NULL AS Person_name'   

所以,现在的问题是如何将上述动态构建的片段添加到我们感兴趣的查询中!
不幸的是,它不能作为一个纯粹在 BigQuery 中的查询,而是在任何 client 或您选择的工具中完成的超级简单任务

我可以演示非技术用户使用我选择的工具 Magnus(Potens.io 的一部分——BigQuery 工具套件)可以轻松完成此操作

下面是 Magnus 工作流的快照,其中只有两个 BigQuery 任务,它们完全重现了上述步骤

如您所见:

在第一个任务中,我们生成具有预期映射列名称的语句并将结果分配给名为var_columns_list 的参数(在工作流执行后它将获得预期值)

在第二个任务中,我们只是简单地使用该参数构建动态 sql

此外,您可以注意到,我没有使用对 project.dataset.Table1 和 project.dataset.Mappingtable 等表的简单引用 - 我使用的是 <var_project_dataset>.Table1 和 <var_project_dataset>.Mappingtable,并且参数 var_project_dataset 是在参数面板中设置的

运行该工作流程后,我们得到如下所示的预期结果

在执行之前是

显然,这是一个简化的示例,只有当您具有基本的列类型(没有结构和数组)时,它才会按原样工作。仍然好消息是这种方法可以轻松处理您在问题中提到的 200 甚至更多列。

无论如何,我认为上面的例子对你来说是一个好的开始!

披露:我是 Potens.io 团队的作者和领导者,这反映在我的个人资料中。我也是云平台的 Google 开发专家和 BigQuery Mate Chrome 扩展的作者

【讨论】:

    【解决方案2】:

    BigQuery 现在支持动态 SQL。基于 Mikhail 的回答,您可以使用以下方法生成他的查询:

    EXECUTE IMMEDIATE format("""
       CREATE OR REPLACE TABLE dataset.Table1 AS 
       SELECT NULL AS %s, NULL AS %s
       FROM (SELECT 1) WHERE FALSE UNION ALL
       SELECT * FROM dataset.Table1  
    """, 'custColum1', 'custColum2')
    

    更多详情,请看这篇文章: https://towardsdatascience.com/how-to-use-dynamic-sql-in-bigquery-8c04dcc0f0de

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-25
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2010-09-14
    相关资源
    最近更新 更多