无法将 BigQuery 旧版 SQL 转换为 HAVING LEFT(...) 的标准 SQL

Posted

技术标签:

【中文标题】无法将 BigQuery 旧版 SQL 转换为 HAVING LEFT(...) 的标准 SQL【英文标题】:Unable to translate BigQuery legacy SQL to standard SQL for HAVING LEFT(...) 【发布时间】:2019-06-29 16:47:40 【问题描述】:

我想使用BigQuery Standard SQL 进行类似this one 的查询:

SELECT package, COUNT(*) count
FROM (
  SELECT REGEXP_EXTRACT(line, r' ([a-z0-9\._]*)\.') package, id
  FROM (
    SELECT SPLIT(content, '\n') line, id
    FROM [github-groovy-files:github.contents] 
    WHERE content CONTAINS 'import'
    HAVING LEFT(line, 6)='import' )
    GROUP BY package, id
  )
GROUP BY 1
ORDER BY count DESC
LIMIT 30;

我无法通过这样的事情(有效但不能 GROUP 或 COUNT):

with lines as 
(SELECT SPLIT(c.content, '\n') line, c.id as id
      FROM `<dataset>.contents` c, `<dataset>.files` f 
      WHERE c.id = f.id AND f.path LIKE '%.groovy')
select 
  array(select REGEXP_REPLACE(l, r'import |;', '') AS class from unnest(line) as l where l like 'import %') imports, id
from lines;

LEFT() 不在标准 SQL 中,似乎没有可以接受数组类型的函数。

【问题讨论】:

【参考方案1】:

LEFT() 不在标准 SQL 中...

在 BigQuery 标准 SQL 中,您可以使用 SUBSTR(value, position[, length]) 代替旧版的 LEFT

... 似乎没有一个函数可以接受数组类型。

有很多 Array's related functions 以及接受数组作为参数的函数 - 例如 UNNEST()

我想将 BigQuery 标准 SQL 用于这样的查询:

下面是 BigQuery Standard SQL 的等效查询

SELECT package, COUNT(*) COUNT
FROM (
  SELECT REGEXP_EXTRACT(line, r' ([a-z0-9\._]*)\.') package, id
  FROM (
    SELECT line, id
    FROM `github-groovy-files.github.contents`,
    UNNEST(SPLIT(content, '\n')) line
    WHERE SUBSTR(line, 1, 6)='import' 
  )
  GROUP BY package, id
)
GROUP BY 1
ORDER BY COUNT DESC
LIMIT 30

你可以用WHERE line LIKE 'import%'代替WHERE SUBSTR(line, 1, 6)='import'

另外请注意,这个查询可以用多种方式编写 - 所以在我上面的示例中,我专注于将您的查询“转换”为从传统 sql 到标准 sql,同时保留原始查询的核心结构和方法

但是,如果您想使用标准 SQL 的强大功能来重写它 - 您最终会得到如下所示的内容

SELECT REGEXP_EXTRACT(line, r' ([a-z0-9\._]*)\.') package, COUNT(DISTINCT id) count
FROM `github-groovy-files.github.contents`,
UNNEST(SPLIT(content, '\n')) line
WHERE line LIKE 'import%' 
GROUP BY 1
ORDER BY count DESC
LIMIT 30

【讨论】:

谢谢。我不确定我是如何错过SUBSTR() 的。我试图UNNEST(),但我做的不对。再次感谢,这很好用。 当然。很高兴它有帮助:o)

以上是关于无法将 BigQuery 旧版 SQL 转换为 HAVING LEFT(...) 的标准 SQL的主要内容,如果未能解决你的问题,请参考以下文章

如何将旧版 SQL BigQuery 转换为标准 SQL?

如何在 BigQuery 中将此旧版 SQL 转换为标准 SQL?

标准 sql 中的 bigquery 旧版 sql POSITION() 函数

如何在 BigQuery 标准 SQL 中将时间戳转换为秒

BigQuery 中用于 Google Analytics 数据的标准 SQL 还是旧版 SQL?

在 BigQuery 中使用 dryRun 区分标准和旧版 SQL 查询的替代方法?