Создать диапазоны на основе данных - PullRequest
1 голос
/ 10 февраля 2020

У меня продукты продаются по разным ценам. Я хочу видеть, сколько продуктов было продано в определенном ценовом диапазоне. Для этого мне нужно go просмотреть данные и посмотреть, как разделить диапазоны, а затем получить количество продуктов в этом диапазоне.

Данные выглядят так, как показано ниже -

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

Цены находятся в плавающем, поэтому диапазоны должны заботиться о значениях плавающих. Это возможно?

Ответы [ 3 ]

1 голос
/ 10 февраля 2020

Ниже для BigQuery Standard 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    
1 голос
/ 11 февраля 2020

Ни один из текущих ответов, по-видимому, не отвечает на вопрос: «Как мне сгенерировать диапазон» (поскольку оба ответа предполагают диапазон 0–50).

То, что вам нужно, - это гистограмма, и Вы можете найти этот ответ здесь:

Теперь, если вы хотите сделать круглые шаги между каждым ведром:


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

enter image description here

С этими ведрами вы можете получить гистограмму сейчас:

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

enter image description here

Если вам также нужны ведра с 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)

enter image description here

1 голос
/ 10 февраля 2020

Вы можете использовать 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;

Вы можете объединить нижнюю и верхнюю границу вместе, но кажется полезным хранить их в двух столбцах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...