Bigquery:将 SPLIT() 输出行分解为多列

Posted

技术标签:

【中文标题】Bigquery:将 SPLIT() 输出行分解为多列【英文标题】:Bigquery: explode SPLIT() output rows into multiple columns 【发布时间】:2016-05-12 18:35:30 【问题描述】:

我在一列中有一个长字符串,需要将其分解为多行,然后拆分为多列。数据看起来像:((a:10,b:20,c:test1)(a:40,b:50,c:test2)(a:60,b:70,c:test3))。当我应用 split 和 regexp_replace 时,我得到了类似的结果

选择 SPLIT(REGEXP_REPLACE(REGEXP_REPLACE(message, r'))',''), r'((','') ,')(') as msg FROM [mydataset.mytable]

输出:

味精 a:10,b:20,c:test1 a:40,b:50,c:test2 a:60,b:70,c:test3

我要找的是: a b c 10 20 测试1 40 50 测试2 60 70 测试3

我再次使用 split 按 (,) 拆分行,但它只给我一行而不是 3。非常感谢您的帮助。

【问题讨论】:

实际数据是长字符串,大约分成40行。并且行数不固定。 【参考方案1】:

试试下面的例子

SELECT
  MIN(CASE WHEN name = 'a' THEN value END) AS a,
  MIN(CASE WHEN name = 'b' THEN value END) AS b,
  MIN(CASE WHEN name = 'c' THEN value END) AS c
FROM (
  SELECT
    message, msg, 
    REGEXP_EXTRACT(pair, r'(\w*):') AS name, 
    REGEXP_EXTRACT(pair, r':(\w*)') AS value
  FROM (
    SELECT message, msg, 
      SPLIT(msg) AS pair
    FROM (
      SELECT message, 
        SPLIT(REPLACE(REPLACE(message, '))',''), '((','') ,')(') AS msg
      FROM 
        (SELECT '((a:10,b:20,c:test1)(a:40,b:50,c:test2)(a:60,b:70,c:test3))' AS message),
        (SELECT '((a:12,b:22,c:test4)(a:42,b:52,c:test5)(a:62,b:72,c:test6))' AS message),
    )
  )
) 
GROUP BY message, msg

【讨论】:

非常感谢 Mikhail,这个解决方案对我有用 :)【参考方案2】:

这是使用standard SQL 的替代解决方案(取消选中“显示选项”下的“使用旧版 SQL”框),它仍然相对冗长但需要较少的文本操作:

WITH MyTable AS (
  SELECT messages
  FROM UNNEST(['((a:10,b:20,c:test1)(a:40,b:50,c:test2)(a:60,b:70,c:test3))',
               '((a:12,b:22,c:test4)(a:42,b:52,c:test5)(a:62,b:72,c:test6))'])
    AS messages)
SELECT
  (SELECT value FROM UNNEST(message_parts) WHERE name = 'a') AS a,
  (SELECT value FROM UNNEST(message_parts) WHERE name = 'b') AS b,
  (SELECT value FROM UNNEST(message_parts) WHERE name = 'c') AS c
FROM (
  SELECT ARRAY(SELECT AS STRUCT
                 SPLIT(part, ':')[OFFSET(0)] AS name,
                 SPLIT(part, ':')[OFFSET(1)] AS value
               FROM UNNEST(SPLIT(message, ',')) AS part) AS message_parts
  FROM (SELECT message FROM MyTable,
          UNNEST(REGEXP_EXTRACT_ALL(messages, r'\(([^\(\)]+)\)')) AS message)
);

【讨论】:

我希望 BigQuery 标准 SQL 文档与您最近的相关答案一样好!我真的很喜欢这些例子!谢谢艾略特!! 是的,没问题!看来您也很快掌握了标准 SQL :) 随着我们向公开测试版迈进,我们将继续改进文档。 我在这个答案中看到的唯一问题是初始数据不是问题!如果你重写它来处理非常初始的数据,那就太好了。我认为你最终会得到更沉重的额外转变。所以在我看来in this case 标准sql“需要较少的文本操作”是适用的,或者至少不那么明显。我觉得有更好的方法来使用标准 sql。只是感觉:o) 糟糕,再试一次;我已经解决了这个问题的一个更简单的版本。旧版 BigQuery SQL 和标准 SQL 解决方案都相对冗长;) 非常感谢 Elliott 的帮助。解决方案效果很好,唯一的事情是我需要在标准 SQL 中运行它。

以上是关于Bigquery:将 SPLIT() 输出行分解为多列的主要内容,如果未能解决你的问题,请参考以下文章

Bigquery 为其余数据输出带有 json 数组对象的不同 zip 行

根据 Python 函数输出指定的列在 Google BigQuery 上进行查询

如何在 BigQuery 中使用 SPLIT 和 CROSS APPLY 函数

split 分割文件

BigQuery 标准 SQL 如何将行转换为列

拆分(分解)熊猫数据框字符串条目以分隔行