Google bigquery 可以计算JSON列中每个键出现的次数吗?

Google bigquery 可以计算JSON列中每个键出现的次数吗?,google-bigquery,Google Bigquery,我有一个BigQuery表,其中有一列包含JSON 我想输出每个键在列中出现的次数,然后按计数降序排序。与所有键关联的值为1 每个对象有一个已知/有限数量的关键点,但我不想依赖它,以防看到的最大对象发生变化 总的来说,键的数量是已知的/有限的,但我不想依赖于在列表发生变化时枚举/更新列表 e、 g.输入:三行,一列名为“json” e、 g.输出:三行,两列,分别命名为“键”和“计数” 考虑到我不想依赖每个对象和整体的有限数量的关键点,最简单的方法是什么 下面是BigQuery标准SQL 看到和

我有一个BigQuery表,其中有一列包含JSON

我想输出每个键在列中出现的次数,然后按计数降序排序。与所有键关联的值为
1

每个对象有一个已知/有限数量的关键点,但我不想依赖它,以防看到的最大对象发生变化

总的来说,键的数量是已知的/有限的,但我不想依赖于在列表发生变化时枚举/更新列表

e、 g.输入:三行,一列名为“json”

e、 g.输出:三行,两列,分别命名为“键”和“计数”

考虑到我不想依赖每个对象和整体的有限数量的关键点,最简单的方法是什么

下面是BigQuery标准SQL

看到和

注意:parseJson UDF足够通用,可以处理任何json,因此您可以使用下面的输入尝试上面的代码,它仍然可以工作:

WITH theTable AS (
  SELECT '{"json":{"A":"1"}}' AS json UNION ALL 
  SELECT '{"json":{"B":"1"}}' AS json UNION ALL
  SELECT '{"json":{"B":"1","C":"1"}}' AS json UNION ALL
  SELECT '{"A":"1"}' AS json UNION ALL 
  SELECT '{"B":"1"}' AS json UNION ALL
  SELECT '{"B":"1","C":"1"}' AS json
)

输出:

key count    
B       2    
A       1    
C       1    
key count    
B       4    
A       2    
C       2    
添加了BigQuery遗留SQL的版本

为了在这里演示和进一步测试的简单性,我在这里使用传统SQL UDF的内联版本<旧式SQL中的代码>内联版本不受官方支持-因此,如果它对您有效-您需要对其进行轻微转换-有关BigQuery旧式SQL中UDF的详细信息,请参阅

SELECT key, COUNT(1) as cnt
FROM JS((
  SELECT json FROM  
    (SELECT '{"json":{"A":"1"}}' AS json),
    (SELECT '{"json":{"B":"1"}}' AS json),
    (SELECT '{"json":{"B":"1","C":"1"}}' AS json),
    (SELECT '{"A":"1"}' AS json),
    (SELECT '{"B":"1"}' AS json),
    (SELECT '{"B":"1","C":"1"}' AS json)
  ),
  json,                                    // Input columns
  "[{name: 'parent', type:'string'},       // Output schema
   {name: 'key', type:'string'},
   {name: 'value', type:'string'}]",
   "function(r, emit) {                    // The function
      processKey(JSON.parse(r.json), '');
      function processKey(node, parent) {
        Object.keys(node).map(function(key) {
          value = node[key].toString();
          if (value !== '[object Object]') {
            emit({parent:parent, key:key, value:value});
          } else {
            if (parent !== '' && parent.substr(parent.length-1) !== '.') {parent += '.'};
            processKey(node[key], parent + key);
          };
        });         
      };
    }"
  )
GROUP BY key
ORDER BY cnt DESC  

如果禁用传统SQL,您可以使用新的bigquery REGEX_EXTRACT_ALL函数,这似乎正是您所需要的:

请编辑您的问题,以显示您遇到问题的代码,然后我们可以尝试帮助解决特定问题。你也可以阅读。至少提供一些简单的示例,显示您的输入数据和预期结果。这将是我认为的最终最小值(我有相对总的工作代码,它依赖于每个对象的有限数量的键和整体的有限数量的键,但在没有这些约束的情况下,我想不出一种方法)澄清-您的输入示例代表三行或一行输入和输出都是三行,虽然这是一个巧合,因为这个数字与“重要”匹配,所以-您可以通过使用投票下方张贴答案左侧的勾号来标记接受答案。看看为什么它很重要!对答案进行投票也很重要。投票选出有帮助的答案。还有更多。。。当有人回答你的问题时,你可以查看该怎么办-。谢谢!不幸的是,这是一个模式分析仪表板,它还不支持标准SQL。如果一周内没有遗留SQL解决方案,我将接受您的回答。@AndreyFedorov-刚刚添加了bigquery遗留SQL的版本您可以通过将
#StandardSQL
放在查询的第一行(取决于仪表板在发送到bigquery之前是否修改文本)在仪表板上使用标准SQL.至于让查询进入模式,我建议在bigquery中使用非遗留sql作为视图。模式应该能够在没有问题的情况下查询视图。
WITH theTable AS (
  SELECT '{"json":{"A":"1"}}' AS json UNION ALL 
  SELECT '{"json":{"B":"1"}}' AS json UNION ALL
  SELECT '{"json":{"B":"1","C":"1"}}' AS json UNION ALL
  SELECT '{"A":"1"}' AS json UNION ALL 
  SELECT '{"B":"1"}' AS json UNION ALL
  SELECT '{"B":"1","C":"1"}' AS json
key count    
B       4    
A       2    
C       2    
SELECT key, COUNT(1) as cnt
FROM JS((
  SELECT json FROM  
    (SELECT '{"json":{"A":"1"}}' AS json),
    (SELECT '{"json":{"B":"1"}}' AS json),
    (SELECT '{"json":{"B":"1","C":"1"}}' AS json),
    (SELECT '{"A":"1"}' AS json),
    (SELECT '{"B":"1"}' AS json),
    (SELECT '{"B":"1","C":"1"}' AS json)
  ),
  json,                                    // Input columns
  "[{name: 'parent', type:'string'},       // Output schema
   {name: 'key', type:'string'},
   {name: 'value', type:'string'}]",
   "function(r, emit) {                    // The function
      processKey(JSON.parse(r.json), '');
      function processKey(node, parent) {
        Object.keys(node).map(function(key) {
          value = node[key].toString();
          if (value !== '[object Object]') {
            emit({parent:parent, key:key, value:value});
          } else {
            if (parent !== '' && parent.substr(parent.length-1) !== '.') {parent += '.'};
            processKey(node[key], parent + key);
          };
        });         
      };
    }"
  )
GROUP BY key
ORDER BY cnt DESC