【问题标题】:How to search for rows containing specific words then return count of each word?如何搜索包含特定单词的行然后返回每个单词的计数?
【发布时间】:2016-10-07 09:18:54
【问题描述】:

我尝试在 Google BigQuery 中查询 150,000 行数据。

Text 列包含各种长度的文本,我想从中查询特定的关键字。

我已经了解了下面的查询,它返回包含特定关键字的所有行(例如 facebook):

SELECT Text From Data.Set_1 
WHERE Text CONTAINS 'facebook'

问题:

1) 如何改进查询,使其返回新列中“文本”中关键字“facebook”的所有出现次数?

2) 我如何将其升级为多个关键字(facebook、cnn、bbc、twitter)并返回数据中存在的每个关键字的总数(例如 facebook 42、cnn 54、bbc 88、twitter 49)?

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    对于 BigQuery 旧版 SQL

    SELECT 
      keyword, 
      COUNT(1) AS rows, 
      SUM(INTEGER((LENGTH(Text) - LENGTH(REPLACE(Text, keyword, ''))) / LENGTH(keyword))) AS occurences 
    FROM YourTable 
    CROSS JOIN keywords
    WHERE Text CONTAINS keyword
    GROUP BY keyword
    

    使用示例

    SELECT 
      keyword, 
      COUNT(1) AS rows, 
      SUM(INTEGER((LENGTH(Text) - LENGTH(REPLACE(Text, keyword, ''))) / LENGTH(keyword))) AS occurences 
    FROM (
      SELECT Text FROM
        (SELECT 'facebookfacebookcnnbbccnn' AS Text),
        (SELECT 'facebook' AS Text), 
        (SELECT 'cnn' AS Text)
    ) AS words 
    CROSS JOIN (
      SELECT keyword FROM 
        (SELECT 'facebook' AS keyword),
        (SELECT 'cnn' AS keyword), 
        (SELECT 'bbc' AS keyword)
    ) AS keywords
    WHERE Text CONTAINS keyword
    GROUP BY keyword
    

    对于 BigQuery 标准 SQL(请参阅 Enabling Standard SQL

    SELECT 
      keyword, 
      COUNT(1) AS `rows`, 
      SUM((LENGTH(Text) - LENGTH(REPLACE(Text, keyword, ''))) / LENGTH(keyword)) AS occurences  
    FROM YourTable 
    JOIN keywords
    ON STRPOS(Text, keyword) > 0
    GROUP BY keyword
    

    使用示例

    WITH keywords AS (
      SELECT 'facebook' AS keyword UNION ALL
      SELECT 'cnn' AS keyword UNION ALL
      SELECT 'bbc' AS keyword 
    ),
    words AS (
      SELECT 'facebookfacebookcnnbbccnn' AS Text UNION ALL
      SELECT 'facebook' AS Text UNION ALL
      SELECT 'cnn' AS Text 
    )
    SELECT 
      keyword, 
      COUNT(1) AS `rows`, 
      SUM((LENGTH(Text) - LENGTH(REPLACE(Text, keyword, ''))) / LENGTH(keyword)) AS occurences  
    FROM words 
    JOIN keywords
    ON STRPOS(Text, keyword) > 0
    GROUP BY keyword
    

    【讨论】:

    • “Text LIKE CONCAT('%', keyword, '%')”很危险,因为关键字可能包含需要转义的特殊字符。它的性能也不是很好。在这里使用的更好的函数是 "STRPOS(Text, keyword) > 0"
    • 这完美!谢谢米哈伊尔。另外 - 这个查询有没有办法扫描两列的关键字?例如 A 列:文本,B 列:Text_2
    • 我的建议是:如果此答案解决了您的问题并帮助了您 - 接受它。至少这会给你更多的未来声誉点。然后尝试采用此解决方案来应对您的新“挑战”(有两列)。尝试提出一些问题,如果仍然存在问题 - 提出/发布新问题,我们将很乐意提供帮助
    • 顺便说一句,作为提示 - 而不是只使用 Text - 您可以连接 TextText_2 - 请参阅 cloud.google.com/bigquery/sql-reference/…。希望这个提示会让你更容易:o)
    【解决方案2】:

    您可以使用派生表来包含您要查找的所有单词,然后使用聚合来计算匹配项:

    SELECT w.keyword, COUNT(s.Text)
    From (SELECT 'facebook' as keyword UNION ALL
          SELECT 'cnn'
         ) w LEFT JOIN
         Data.Set_1 s
         ON s.Text CONTAINS w.keyword
    GROUP BY w.keyword;
    

    请注意:这不是特别有效。效果应该与关键字的数量大致呈线性关系。

    【讨论】:

    • 嗨,戈登——你不睡觉吗?我总是在 Stackoverflow 上看到你 :)
    • 谢谢 Gordon,这看起来很有用 - 我对 SQL 还很陌生,所以请耐心等待。我能问一下为什么是“w”吗?在关键字和“s”之前。在文本之前?
    • @EdMoonLittle 。 . .因为我建议在所有具有多个表的查询中使用表别名(在只有一个表的查询中可选)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多