如何优化 google-bigquery 以从大数据表中查找最常见的类别?
Posted
技术标签:
【中文标题】如何优化 google-bigquery 以从大数据表中查找最常见的类别?【英文标题】:how to optimize google-bigquery for finding most frequent categories from big data table? 【发布时间】:2019-04-21 00:37:00 【问题描述】:我在芝加哥犯罪数据集上使用 google-bigquery
。但是,我想从primary_type
列中找出每个不同的block
最常见的犯罪类型。为此,我关注standardSQL
。
数据:
由于芝加哥犯罪数据比较大,有官网可以预览数据集:crime data on Google cloud
我目前的标准 SQL:
SELECT primary_type,block, COUNT(*) as count
FROM `bigquery-public-data.chicago_crime.crime`
HAVING COUNT(*) = (SELECT MAX(count)
FROM (SELECT primary_type, COUNT(*) as count FROM `bigquery-public-data.chicago_crime.crime` GROUP BY primary_type, block) `bigquery-public-data.chicago_crime.crime`)
我上面的查询的问题是它现在有一个错误,对我来说,这个查询效率很低,即使我修复了错误。如何修复和优化上述查询?
如何在标准 SQL 中使用正则表达式:
要计算每个区块最常见的类型,包括南北,我必须处理regex
,例如033XX S WOOD ST
,我应该只得到S WOOT ST
和033XX N WOOD ST
。我需要得到N WOOD ST
并计算这些。我该怎么做?
想要的输出:
在我想要的输出中,对于每个块,例如 WOOD ST (North (N WOOD ST)
和 South(S WOOD ST))
。我想找到最常见的犯罪类型。在我的最终输出中,我期待三列,例如block
、primary_type
、count
。有什么办法可以通过google-bigquery
完成这项工作?
【问题讨论】:
【参考方案1】:以下是 BigQuery 标准 SQL
#standardSQL
SELECT
block,
ARRAY_AGG(STRUCT(primary_type, cnt) ORDER BY cnt DESC LIMIT 1)[OFFSET(0)].*
FROM (
SELECT
block,
primary_type,
COUNT(*) cnt
FROM `bigquery-public-data.chicago_crime.crime`
GROUP BY block, primary_type
)
GROUP BY block
我怎样才能获得街区 WOOD ST 上最常见的犯罪类型?有什么技巧可以做到这一点吗?
我不熟悉这些数据的具体细节,但从简要一瞥 - 我认为您可以在下面尝试
#standardSQL
SELECT
block,
ARRAY_AGG(STRUCT(primary_type, cnt) ORDER BY cnt DESC LIMIT 1)[OFFSET(0)].*
FROM (
SELECT
SUBSTR(block, 8) block,
primary_type,
COUNT(*) cnt
FROM `bigquery-public-data.chicago_crime.crime`
GROUP BY block, primary_type
)
GROUP BY block
【讨论】:
你能给我几行解释你的查询吗?我想了解您的解决方案。谢谢。 当然。内部 SELECT 只是简单地计算每个块和类别的计数。然后,外部 SELECT 只为每个块选择最常见的类别! 我只是想了解您查询的语法,为什么要使用ARRAY_AGG()[OFFSET(0)].* FROM()
?为什么在这里使用.*
操作?
尝试删除.*
,你会看到不同:o)
它类似于使用SELECT * FROM table
从给定表中选择所有列 - 这里相同 - 它从 STRUCT 中选择所有字段。很高兴它有帮助:o)【参考方案2】:
这应该为您提供最常见的犯罪率
内部查询计数计算犯罪频率,窗口划分函数根据块划分的犯罪频率降序计算排名。外部查询 where 子句 rank =1 只返回最常见的犯罪。您可以更改外部查询 where 子句,通过使其排名 来获得前 5 名常见犯罪
select * from
(SELECT block, primary_type, count(primary_type) as crime_frquency,
ROW_NUMBER() OVER (PARTITION BY block ORDER BY count(primary_type) DESC) AS rank
FROM `bigquery-public-data.chicago_crime.crime`
group by block, primary_type)
where rank = 1
【讨论】:
以上是关于如何优化 google-bigquery 以从大数据表中查找最常见的类别?的主要内容,如果未能解决你的问题,请参考以下文章
如何同步调用 google-bigquery 删除和插入 API?