Bigquery:正则表达式提取后 COUNT/GROUP BY

Bigquery : COUNT/GROUP BY after regex extraction

我是 bigquery 的新手。我有一个 table MOVIES 具有以下架构:

[SchemaField('movieId', 'INTEGER', 'NULLABLE', None, ()),
 SchemaField('title', 'STRING', 'NULLABLE', None, ()),
 SchemaField('genres', 'STRING', 'NULLABLE', None, ())]

电影的名字是这样的:Pharaoh's Army (1995)

我想看看哪一年拍的电视剧最多。我已经设法从标题中提取年份并且只保留像这样的戏剧电影:

q4 = """
select 
  movies.title,
  regexp_extract(title, r'\((\d{4})\)') as year,
from assignment-344206.movie_lens_20M.MOVIES movies
where movies.genres = "Drama"
order by year desc
limit 5
"""
query_job_4 = client.query(q4)
query_job_4.to_dataframe()

现在我需要按年份分组,然后对每一组进行计数,以找出戏剧最多的年份。我试过了:

q4 = """
select 
  movies.title,
  regexp_extract(title, r'\((\d{4})\)') as year,
  count(year) as nb_per_year
from assignment-344206.movie_lens_20M.MOVIES movies
where movies.genres = "Drama"
group by year
order by year desc
limit 5
"""

但我收到以下错误 BadRequest: 400 Unrecognized name: year at [5:9] 我不明白。没有 group by 名称 yearorder by year desc 中被识别,为什么它现在不能识别它?

聚合器 COUNT() 无法知道 year,因为您只是在上面的行中将其创建为 category/group。 ORDER BY 在 grouping/aggregations 之后执行,因此它可以知道字段 year.

执行的大致顺序是afaik

  1. 从输入tables
  2. 加入 table 条记录
  3. WHERE 字段筛选器
  4. GROUP BY 聚合字段
  5. HAVING 聚合过滤器
  6. WINDOW 函数
  7. 符合条件 window 字段过滤器
  8. 不同的结果字段
  9. 按结果字段排序
  10. LIMIT 和 OFFSET 结果行
  11. SELECT (output/print) 输出字段

(像 UNION 这样的设置操作只适用于查询结果 - 不确定在哪里列出它们 - 它们是第一个还是最后一个取决于你如何看待它)

根据您的 year 中是否有 NULL 值,您可以尝试 COUNT(*)COUNT(title) 甚至 COUNT(regexp_extract(title, r'\((\d{4})\)'))

如果您不想要额外的正则表达式但需要字段 year,您可以在 CTE WITH 中准备 table 并在查询引用中进行分组CTE。

为了补充 Martin Weitzmann 的回答,如果您决定使用 WITH,下面是此类场景的 code/script 实现。 with 可以用作最终查询的单个表达式中的临时 table。有关 with 行为的更多详细信息,请参见 with clause 页面。

query:此查询显示 with 在您的案例中的用法。您可以在 BigQuery UI.运行 上执行此操作 UI。

with movies as (
    select 
        title,
        SAFE_CAST(regexp_extract(title, r'\((\d{4})\)') AS INT64) as year,
        genres
        from `projectid.datasetid.table`
)
select count(1) as movies_per_year, year
from movies
where genres = "Drama"
group by year
order by year desc

code:用上面的查询

替换QUERY
from google.cloud import bigquery

client = bigquery.Client()

query = """ QUERY """

query_job = client.query(query)
df = query_job.to_dataframe()
print(df.head())

输出

year | movier per year
2008 | 1
2003 | 1
2001 | 1
1994 | 2
1993 | 1
  ...