错误:TABLE_QUERY表达式无法查询BigQuery表

时间:2016-04-17 06:41:33

标签: google-bigquery

这是关于Jordans的回答问题:Weird error in BigQuery

我用来查询" Table_Query"中的参考表。退出一段时间。现在,根据Joradan最近提到的变化,我们的许多疑问都被打破了...我想请求社群建议我们正在做什么的替代解决方案。

我有包含事件的表(" MyTable_YYYYMMDD")。我想查询一段特定(或几个)广告系列的数据。该广告系列的期间存储在包含所有广告系列数据(ID,StartCampaignDate,EndCampaignDate)的表格中。为了只查询相关表,我们使用Table_Query(),在TableQuery()中,我们根据广告系列数据构建所有相关表名的列表。 此查询使用不同的参数以多种形式运行多次。使用通配符函数(而不是查询整个数据集)的原因是性能,执行成本和维护成本。因此,让它查询所有表并过滤结果不是一个选项,因为它会导致执行成本过高。

示例查询将如下所示:

SELECT
  *
FROM
  TABLE_QUERY([MyProject:MyDataSet] 'table_id IN  
  (SELECT CONCAT("MyTable_",STRING(Year*100+Month)) TBL_NAME  
    FROM DWH.Dim_Periods P  
    CROSS JOIN DWH.Campaigns AS LC  
    WHERE ID IN ("86254e5a-b856-3b5a-85e1-0f5ab3ff20d6") 
    AND DATE(P.Date) BETWEEN DATE(StartCampaignDate) AND DATE(EndCampaignDate))')

现在已经破了...... 我的问题 - 信息,你应该查询哪些表存储在一个参考表上,当" TableQuery"时,你将如何查询相关的表(分区)?不再允许查询引用表吗?

非常感谢

2 个答案:

答案 0 :(得分:2)

我看到的“简单”方式是分为两步 第1步 - 构建列表,用于过滤table_id的

SELECT GROUP_CONCAT_UNQUOTED(
                   CONCAT('"',"MyTable_",STRING(Year*100+Month),'"')
       ) TBL_NAME_LIST 
FROM DWH.Dim_Periods P  
CROSS JOIN DWH.Campaigns AS LC  
WHERE ID IN ("86254e5a-b856-3b5a-85e1-0f5ab3ff20d6") 
AND DATE(P.Date) BETWEEN DATE(StartCampaignDate) AND DATE(EndCampaignDate)

请注意您的查询中的更改,以将结果转换为您将在步骤2中使用的列表

第2步 - 最终查询

SELECT
  *
FROM
  TABLE_QUERY([MyProject:MyDataSet], 
              'table_id IN (<paste list (TBL_NAME_LIST) built in first query>)')

以上步骤很容易在您可能使用的任何客户端中实施 如果你在BigQuery Web UI中使用它 - 这会让你做一些你可能不满意的额外手动“动作”

我的答案显而易见,你很可能已经将此作为选项,但想提及

答案 1 :(得分:0)

这不是理想的解决方案。但它似乎做了这件事。

在我之前的查询中,我将ID List作为参数传递给构造查询的外部进程。我希望这个过程不会意识到查询中实现的任何逻辑。

最终我们提出了这个解决方案:

我们传递一个包含每个ID的相关元数据的JSON,而不是传递ID列表。我们在Table_Query()函数中解析这个JSON。因此,我们不是查询物理参考表,而是查询我们放入JSON的某种“表变量”。
下面是一个示例查询,它在演示此解决方案的公共数据集上运行。

    SELECT
  YEAR,
  COUNT (*) CNT
FROM
  TABLE_QUERY([fh-bigquery:weather_gsod], 'table_id in
(Select table_id
From
(Select table_id,concat(Right(table_id,4),"0101") as TBL_Date from [fh-bigquery:weather_gsod.__TABLES_SUMMARY__]
where table_id Contains "gsod"
)TBLs
CROSS JOIN 
(select 
Regexp_Replace(Regexp_extract(SPLIT(DatesInput,"},{"),r"\"fromDate\":\"(\d\d\d\d-\d\d-\d\d)\""),"-","") as fromDate,
Regexp_Replace(Regexp_extract(SPLIT(DatesInput,"},{"),r"\"toDate\":\"(\d\d\d\d-\d\d-\d\d)\""),"-","") as toDate,
FROM
(Select
"[  
      {  
         \"CycleID\":\"123456\",
         \"fromDate\":\"1929-01-01\",
         \"toDate\":\"1950-01-10\"
      },{  
         \"CycleID\":\"123456\",
         \"fromDate\":\"1970-02-01\",
         \"toDate\":\"2000-02-10\"
      }
   ]"
   as DatesInput)) RefDates
   WHERE TBLs.TBL_Date>=RefDates.fromDate
   AND TBLs.TBL_Date<=RefDates.toDate
)')
GROUP BY
  YEAR
ORDER BY
  YEAR

此解决方案并不理想,因为它需要外部流程才能了解存储在参考表中的数据。 理想情况下,BigQuery团队将重新启用这个非常有用的功能。