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
名称 year
在 order by year desc
中被识别,为什么它现在不能识别它?
聚合器 COUNT()
无法知道 year
,因为您只是在上面的行中将其创建为 category/group。 ORDER BY
在 grouping/aggregations 之后执行,因此它可以知道字段 year
.
执行的大致顺序是afaik
- 从输入tables
- 加入 table 条记录
- WHERE 字段筛选器
- GROUP BY 聚合字段
- HAVING 聚合过滤器
- WINDOW 函数
- 符合条件 window 字段过滤器
- 不同的结果字段
- 按结果字段排序
- LIMIT 和 OFFSET 结果行
- 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
...
我是 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
名称 year
在 order by year desc
中被识别,为什么它现在不能识别它?
聚合器 COUNT()
无法知道 year
,因为您只是在上面的行中将其创建为 category/group。 ORDER BY
在 grouping/aggregations 之后执行,因此它可以知道字段 year
.
执行的大致顺序是afaik
- 从输入tables
- 加入 table 条记录
- WHERE 字段筛选器
- GROUP BY 聚合字段
- HAVING 聚合过滤器
- WINDOW 函数
- 符合条件 window 字段过滤器
- 不同的结果字段
- 按结果字段排序
- LIMIT 和 OFFSET 结果行
- 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:用上面的查询
替换QUERYfrom 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
...