大查询中是否可以在SQL Server中执行类似“ EXEC”之类的动态查询?

时间:2019-04-04 17:10:05

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

我有一个包含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(角色编号,人名)。 注意:由于我不知道将映射哪一列,因此无法使用此名称创建table1。

正在考虑是否可以执行创建动态查询之类的操作并按如下所示执行

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

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

2 个答案:

答案 0 :(得分:2)

让我们假设以下简化示例

表1
enter image description here

映射表
enter image description here

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

#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 Workflow的快照,其中只有两个BigQuery Tasks,它们完全在上述步骤中重现

enter image description here

如您所见:

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

enter image description here

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

此外,您会注意到,与使用project.dataset.Table1project.dataset.Mappingtable之类的表的普通引用不同,我使用的是<var_project_dataset>.Table1<var_project_dataset>.Mappingtable和参数var_project_dataset在参数面板中设置

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

enter image description here

在执行之前是

enter image description here

显然,这是简化的示例,并且仅当您具有基本的列类型时才可以按原样工作-没有结构也没有数组。仍然值得庆幸的是,这种方法将轻松处理您在问题中提到的200列甚至更多列。

无论如何,我认为上述示例对您来说是一个好的开始!

披露:我是Potens.io团队的作者兼负责人,这反映在我的个人资料中。我也是Cloud Platform的Google Developer Expert和BigQuery Mate Chrome Extension的作者

答案 1 :(得分:0)

BigQuery现在支持动态SQL。以米哈伊尔的答案为基础,您可以使用以下方法生成他的查询:

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