【问题标题】:Bigquery - Filtering on Repeated Fields Using SemiJoinsBigquery - 使用 SemiJoins 过滤重复字段
【发布时间】:2016-01-14 17:50:32
【问题描述】:

我正在尝试根据重复字段中的项目是否位于另一个表的列中来从一个表中选择记录。当我在我的代码中明确列出我正在测试的项目时,我已经能够做到这一点,但在从另一个表中选择时却不行。让我演示一下使用 trigrams 数据集:

假设我想选择在特定年份出现的所有记录。但我不只是想要那些年的数据——我想要与这些记录相关的所有数据。如果我只想要几年的数据,我可以做这样的事情(而且这很有效):

SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count,
    SOME(cell.value in ('1800', '1801')) WITHIN RECORD AS valid
FROM [publicdata:samples.trigrams]
HAVING valid

但是,我没有将“1800”和“1801”编码到我的查询中,而是有一个表years,其中包含我感兴趣的一组年份。我希望它能够工作:

SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count,
    SOME(cell.value in (SELECT year_as_str FROM [mydataset.years])) WITHIN RECORD AS valid
FROM [publicdata:samples.trigrams]
HAVING valid

这不起作用,因为 bigquery 要求半联接是 WHERE 或 HAVING 子句的一部分。

所以我尝试重新排列(回到第一个查询):

SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count
FROM [publicdata:samples.trigrams]
HAVING SOME(cell.value in ('1801', '1802')) WITHIN RECORD

这会导致错误Encountered " "WITHIN" "WITHIN "" ... Was expecting <EOF>

所以现在没有WITHIN RECORD:

SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count
FROM [publicdata:samples.trigrams]
HAVING SOME(cell.value in ('1801', '1802'))

这会导致错误SELECT clause has mix of aggregations '...' and fields '...' without GROUP BY clause

但我没有汇总!所以现在我将过滤器移动到WHERE:

SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count
FROM [publicdata:samples.trigrams]
WHERE SOME(cell.value in ('1801', '1802'))

这告诉我Invalid function name: SOME。什么?!

有没有办法通过 BigQuery 获得我正在寻找的行为?

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    下面解决了您的示例,我希望您能够将其扩展到您的实际用例(如果您喜欢解决方案)

    SELECT 
        ngram, cell.value, cell.volume_count, 
        cell.volume_fraction, cell.page_count, cell.match_count
    FROM [publicdata:samples.trigrams] AS trigrams
    JOIN (
      SELECT ngram AS qualified
      FROM (
        FLATTEN((SELECT ngram, cell.value AS value
          FROM (FLATTEN([publicdata:samples.trigrams], cell.value))), value)
      ) AS t
      JOIN [mydataset.years] AS y
      ON y.year_as_str = t.value
      GROUP BY 1
    ) AS valid
    ON valid.qualified = trigrams.ngram
    

    请注意 [publicdata:samples.trigrams] 中的字段 cell.value 是 REPEATED STRING - 这就是为什么你会看到“额外”的 FLATTEN 东西

    【讨论】:

      【解决方案2】:

      您可以为此使用OMIT RECORD IF 子句。这可能需要双重否定,因为您需要省略满足某些条件的记录。以下查询应该有效:

      SELECT ngram, first, second, third, fourth, fifth, cell.value, cell.volume_count
      FROM [publicdata:samples.trigrams]
      OMIT RECORD IF EVERY(cell.value NOT IN ('1801', '1802'))
      

      【讨论】:

      • 不幸的是,这不起作用,因为如果我将('1801', '1802') 替换为子选择查询,则整个查询将失败。 Mikhail 的过滤器+自连接解决方​​案有效
      • 好点,对不起!我最初错过了你问题的那一部分。
      猜你喜欢
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多