SQL 'FROM UNNEST' 的语义是啥?

Posted

技术标签:

【中文标题】SQL \'FROM UNNEST\' 的语义是啥?【英文标题】:What are the semantics of SQL 'FROM UNNEST'?SQL 'FROM UNNEST' 的语义是什么? 【发布时间】:2018-10-23 17:09:10 【问题描述】:

在阅读正式语言的表达式时,我习惯于从内到外阅读,即理解子表达式并构建整体。在this SQL snippet:

SELECT 
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'TITLE') AS level_id,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'url') AS url
FROM `events_20180725`
WHERE event_name = 'SCI_ERROR'

一个子表达式是

SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'TITLE'

这不是一个普通的子查询:如果我尝试自己运行它,我会得到一个错误,因为event_params 不是一个数组。所以看来

UNNEST 可以与数组以外的东西一起使用。 在外部FROM 中使用了表events_20180725 的某种绑定,这使得子查询内的UNNEST 可以访问它。

https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays 包含一些示例(在“查询嵌套数组”下),但实际上并未解释语义。这是怎么回事?

【问题讨论】:

您似乎只是查看了文档中不是最匹配的部分-在我的答案中查看更好的链接 【参考方案1】:

UNNEST 运算符接受一个 ARRAY 并返回一个表,其中 ARRAY 中的每个元素都有一行。您还可以在带有 IN 运算符的 FROM 子句之外使用 UNNEST。

对于大多数元素类型的输入 ARRAY,UNNEST 的输出通常只有一列。这个单列有一个可选的别名,您可以使用它来引用查询中其他地方的列。具有这些元素类型的数组返回多列:

结构 UNNEST 破坏输入 ARRAY 中元素的顺序。使用可选的 WITH OFFSET 子句返回带有数组元素索引的第二列(见下文)。

对于 STRUCT 的输入 ARRAY,UNNEST 为每个 STRUCT 返回一行,并为 STRUCT 中的每个字段返回一个单独的列。每列的别名是对应的 STRUCT 字段的名称。

您可以在更适用的部分 - FROM clause 中阅读更多关于 UNNEST 的信息 - 去那里并向下滚动一点直到 UNNEST 部分

【讨论】:

【参考方案2】:

events_20180725 中选择的外部查询将event_params 引入选择列表的范围。当您将标量子查询放在选择列表中时,该子查询可以引用外部范围内的列。 UNNEST 函数返回一个给定列引用的关系,它将其他列引入子查询的范围,在本例中为keyvalue。在这个标量子查询的情况下:

(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'TITLE')

过滤key = 'TITLE'UNNEST 返回的行限制为键具有该值的行。

【讨论】:

以上是关于SQL 'FROM UNNEST' 的语义是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Google Bigquery SQL UNNEST 和 STRING_AGG

在计算机科学环境中,“语义”一词是啥意思?

Hive中Presto UNNEST函数的等价物是啥

SQL结构化查询语——之DQL语言

SQL命令未正确结束是啥意思

SQL UNNEST 需要别名?