根据数据创建范围

Posted

技术标签:

【中文标题】根据数据创建范围【英文标题】:Create ranges based on the data 【发布时间】:2020-02-10 19:56:47 【问题描述】:

我的产品以不同的价格出售。我想看看在特定价格范围内售出了多少产品。为此,我需要查看数据并查看如何划分范围,然后获取该范围内的产品数量。

数据如下-

Product        Price sold
   A              4.5
   B              45.7
   C              20
   D              20.1
   E              36.8
   F              50

例如,对于上述数据,我看到最小值为 4.5,最大值为 50。因此,我决定将价格范围划分为 - 0-10$、11-20$、21-30$、30- 40 美元,40-50 美元

所以,结果应该是这样的-

Range           No. of products sold
0-10                    1
11-20                   2
21-30                   0
30-40                   1
40-50                   2

价格是浮动的,因此范围应考虑浮动值。这可能吗?

【问题讨论】:

【参考方案1】:

当前的答案似乎都没有回答这个问题:“我如何生成范围”(因为两个答案都假定范围为 0-50)。

您似乎想要的是直方图,您可以在这里找到答案:

https://***.com/a/56447260/132438

现在,如果你想在每个桶之间循环:


WITH data AS (
  SELECT * FROM  `fh-bigquery.public_dump.gdp_capita`
), min_and_max AS (
  SELECT MIN(gdp_capita) min, MAX(gdp_capita) max
  FROM data
), generate_buckets AS (
  SELECT x bucket_min
    , IFNULL(LEAD(x) OVER(ORDER BY x), 1+(SELECT max FROM min_and_max)) bucket_max 
  FROM UNNEST(generate_array(
    (SELECT 0 FROM min_and_max) # min or 0, depending on your start
    , (SELECT max FROM min_and_max)
    , (SELECT POW(10, fhoffa.x.int(LOG10(max-min)))/10 FROM min_and_max) # log10 for round order of 10 steps
  )) x
)

SELECT *
FROM generate_buckets

有了这些桶,你现在可以得到一个直方图:

SELECT bucket_min, bucket_max, COUNT(*) c
FROM generate_buckets
JOIN data
ON data.gdp_capita >= bucket_min AND data.gdp_capita < bucket_max 
GROUP BY 1,2 
ORDER BY 1

如果你还需要 0 个元素的桶:

SELECT * REPLACE(IFNULL(c,0) AS c)
FROM (
  SELECT bucket_min, bucket_max, COUNT(*) c
  FROM generate_buckets
  JOIN data
  ON data.gdp_capita >= bucket_min AND data.gdp_capita < bucket_max AND data.one=generate_buckets.one
  GROUP BY 1,2 
  ORDER BY 1
) 
RIGHT JOIN generate_buckets USING(bucket_min, bucket_max)

【讨论】:

as both answers assume a range 0-50 - 这是不正确的。至少在我的回答中,您可以设置/在内联或查找表中设置任何范围 我的意思是 - 两个答案都带来了固定代码桶。我想添加一个答案,在给定特定数据的情况下选择自己的范围。无论如何,用户似乎对当前接受的答案很满意:) 当然,我仍然看不到我的答案中的范围是如何固定的 - 我认为它非常通用并且允许使用任何范围:o( 我的意思是“固定”,因为“用户必须输入用户想要使用的任何范围”。但是问题的标题是“根据数据创建范围”,所以我想回答我将如何根据表格中显示的数据创建范围。 哦,我现在明白你的意思了:o)【参考方案2】:

以下是 BigQuery 标准 SQL

#standardSQL
WITH price_ranges AS (
  SELECT '0-10' price_range UNION ALL 
  SELECT '11-20' UNION ALL 
  SELECT '21-30' UNION ALL 
  SELECT '30-40' UNION ALL 
  SELECT '40-50' 
)
SELECT price_range, COUNT(1) number_sold
FROM `project.dataset.table`
JOIN price_ranges 
ON CAST(price_sold AS INT64)
  BETWEEN CAST(SPLIT(price_range, '-')[OFFSET(0)] AS INT64) 
  AND CAST(SPLIT(price_range, '-')[OFFSET(1)] AS INT64)
GROUP BY price_range
-- ORDER BY price_range

如果适用于您问题的样本数据 - 结果是

Row price_range number_sold  
1   0-10        1    
2   11-20       2    
3   30-40       1    
4   40-50       2    

【讨论】:

【参考方案3】:

您可以使用generate_array()。我将其表述为:

select lb, lb + 10 as ub, count(d.product)
from unnest(generate_array(0, 50, 10)) lb left join
     data d
     on d.price >= lb and
        d.price < lb + 10
group by lb
order by lb;

您可以将下限和上限连接在一起,但将它们保持在两列中似乎很有用。

【讨论】:

以上是关于根据数据创建范围的主要内容,如果未能解决你的问题,请参考以下文章

js根据时间范围生成时间刻度数据

如何根据两个时间范围列表的交集创建时间范围列表?

需要根据日期范围参数包含不同列的报告

如何根据日期范围创建月份数组

MS Access 根据给定的日期范围选择查询字段

如何根据给定的行数范围从文本文件中分割数据