通配符表和表列中的差异

时间:2018-03-29 14:35:45

标签: sql google-bigquery

我尝试使用JOIN在一系列表格中使用BigQuery Wildcard Tables

当通配符匹配的所有表都具有列fooidbar*.fooid)时,查询才有效。但是,此列是最近添加的,当表通配符与该字段不存在的表匹配时,查询将失败。

Error: Cannot read non-required field 'fooid' as required INT64. 

这是用于演示问题的查询的简化版本,它将从foo和bar中选择更多列。

SELECT foo.foo_id AS foo
FROM `bar.bar*` AS bar_alias
LEFT JOIN bar.foo_map foo ON (bar_alias.fooid = foo.foo_id)
WHERE (_TABLE_SUFFIX BETWEEN  '20170206' AND '20170208')

我已经查看了很多答案,包括BigQuery IF field exists THEN,但无法看到如何将它们与JOIN结合使用,或者当没有列的表格没有已知的。

1 个答案:

答案 0 :(得分:1)

以下是如何出现这种情况的示例,以及如何通过使用列/字段为NULLABLE的空表中的引用模式来解决此问题。假设我有以下两个表:

$ bq query --use_legacy_sql=false \
  "CREATE TABLE tmp_elliottb.bar20180328 (y STRING) AS SELECT 'bar';"

$ bq query --use_legacy_sql=false \
  "CREATE TABLE tmp_elliottb.bar20180329 " \
  "(x INT64 NOT NULL, y STRING) AS SELECT 1, 'foo';"

x在第二个表中具有NOT NULL属性,但第一个表中缺少该列。当我尝试使用表格通配符时出错:

$ bq query --use_legacy_sql=false \
  "SELECT * FROM \`tmp_elliottb.bar*\` " \
  "WHERE _TABLE_SUFFIX BETWEEN '20180301' AND '20180329';"
Waiting on <job id> ... (0s) Current status: DONE   
Error in query string: Error processing job '<job id>': Cannot read non-required field 'x' as required INT64.
Failure details:
- query: Cannot read non-required field 'x' as required INT64.

这是有道理的 - 我说xNOT NULL,但bar20180328表没有列。现在,如果我创建一个与*扩展匹配的新表,但该列没有NOT NULL

$ bq query --use_legacy_sql=false \
  "CREATE TABLE tmp_elliottb.bar_empty (x INT64, y STRING);"
$ bq query --use_legacy_sql=false \
  "SELECT * FROM \`tmp_elliottb.bar*\` " \
  "WHERE _TABLE_SUFFIX BETWEEN '20180301' AND '20180329';"
...
+------+-----+
|  x   |  y  |
+------+-----+
|    1 | foo |
| NULL | bar |
+------+-----+

我得到结果而不是错误。在您的情况下,您需要创建一个名为bar_empty的预期模式的表,但其中没有其他表缺少的字段/列具有NOT NULL属性。

话虽如此,如果可能的话,我强烈建议使用分区表。除了其他好处之外,分区表可以更好地使用,因为它们在所有日子里都具有一致的模式。