【发布时间】:2013-03-06 01:35:35
【问题描述】:
如何编写使直方图渲染更容易的查询?
例如,我们有 1 亿人的年龄,我们想要绘制年龄 0-10、11-20、21-30 等的直方图/桶...查询是什么样的?
有人做过吗?您是否尝试将查询结果连接到 google 电子表格以绘制直方图?
【问题讨论】:
标签: sql google-bigquery
如何编写使直方图渲染更容易的查询?
例如,我们有 1 亿人的年龄,我们想要绘制年龄 0-10、11-20、21-30 等的直方图/桶...查询是什么样的?
有人做过吗?您是否尝试将查询结果连接到 google 电子表格以绘制直方图?
【问题讨论】:
标签: sql google-bigquery
像这样写一个子查询:
(SELECT '1' AS agegroup, count(*) FROM people WHERE AGE <= 10 AND AGE >= 0)
然后你可以这样做:
SELECT * FROM
(SELECT '1' AS agegroup, count(*) FROM people WHERE AGE <= 10 AND AGE >= 0),
(SELECT '2' AS agegroup, count(*) FROM people WHERE AGE <= 20 AND AGE >= 10),
(SELECT '3' AS agegroup, count(*) FROM people WHERE AGE <= 120 AND AGE >= 20)
结果如下:
Row agegroup count
1 1 somenumber
2 2 somenumber
3 3 another number
我希望这对你有帮助。当然在这个年龄段你可以写任何东西:'0 to 10'
【讨论】:
见2019 update, with #standardSQL --Fh
子查询的想法是有效的,就像“CASE WHEN”一样,然后按以下方式进行分组:
SELECT COUNT(field1), bucket
FROM (
SELECT field1, CASE WHEN age >= 0 AND age < 10 THEN 1
WHEN age >= 10 AND age < 20 THEN 2
WHEN age >= 20 AND age < 30 THEN 3
...
ELSE -1 END as bucket
FROM table1)
GROUP BY bucket
或者,如果桶是规则的——你可以只划分并转换为一个整数:
SELECT COUNT(field1), bucket
FROM (
SELECT field1, INTEGER(age / 10) as bucket FROM table1)
GROUP BY bucket
【讨论】:
"0 <= age < 10"、"10 <= age < 20" 等字符串命名存储桶来使事情更清楚。另外,SUM(field1) 不是对年龄值求和吗?我想你想做SELECT 1 只计算桶中的每个年龄一次。
0 <= age < 10 是 0 <= age OR age < 10,至少在 BigQuery 领域。
您正在寻找一个单一的信息向量。我通常会这样查询:
select
count(*) as num,
integer( age / 10 ) as age_group
from mytable
group by age_group
任意组都需要一个大的case 语句。它会很简单,但会更长。如果每个桶包含 N 年,我的示例应该没问题。
【讨论】:
您还可以使用quantiles 聚合运算符快速查看年龄分布。
SELECT
quantiles(age, 10)
FROM mytable
此查询的每一行都对应于年龄列表中该点的年龄。第一个结果是年龄排序列表的 1/10 岁,第二个是 2/10 岁,3/10 岁等。
【讨论】:
APPROX_QUANTILES。 cloud.google.com/bigquery/docs/reference/standard-sql/…
使用交叉连接来获取最小值和最大值(在单个元组上并不那么昂贵),您可以获得任何给定存储桶计数的标准化存储桶列表:
select
min(data.VAL) as min,
max(data.VAL) as max,
count(data.VAL) as num,
integer((data.VAL-value.min)/(value.max-value.min)*8) as group
from [table] data
CROSS JOIN (SELECT MAX(VAL) as max, MIN(VAL) as min, from [table]) value
GROUP BY group
ORDER BY group
在这个例子中,我们得到了 8 个桶(非常不言自明)加上一个用于 null VAL
【讨论】:
使用#standardSQL 和辅助stats 查询,我们可以定义直方图应查看的范围。
这里是 SFO 和 JFK 之间飞行的时间 - 有 10 个桶:
WITH data AS (
SELECT *, ActualElapsedTime datapoint
FROM `fh-bigquery.flights.ontime_201903`
WHERE FlightDate_year = "2018-01-01"
AND Origin = 'SFO' AND Dest = 'JFK'
)
, stats AS (
SELECT min+step*i min, min+step*(i+1)max
FROM (
SELECT max-min diff, min, max, (max-min)/10 step, GENERATE_ARRAY(0, 10, 1) i
FROM (
SELECT MIN(datapoint) min, MAX(datapoint) max
FROM data
)
), UNNEST(i) i
)
SELECT COUNT(*) count, (min+max)/2 avg
FROM data
JOIN stats
ON data.datapoint >= stats.min AND data.datapoint<stats.max
GROUP BY avg
ORDER BY avg
如果您需要整数,请参阅:https://stackoverflow.com/a/60159876/132438
【讨论】:
现在标准 SQL 中有 APPROX_QUANTILES 聚合函数。
SELECT
APPROX_QUANTILES(column, number_of_bins)
...
【讨论】: