NTILE () в BigQuery для неоднородных сегментов - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь выполнить сегментацию RFM в образце набора данных Google Merchandise Store на BigQuery. В моем SQL-запросе NTILE (5) делит строки на 5 сегментов на основе порядка строк и возвращает номер блока, назначенный каждой строке. В этом случае каждое ведро имеет одинаковый размер. Хотелось бы узнать, как вместо этого создавать ведра разных размеров. Например, ведро 1 содержит нижние 10%, ведро 2 содержит следующие 20% записей и т. Д. Спасибо!

#standard SQL    
  SELECT
      fullVisitorId,
      NTILE(5) OVER (ORDER BY last_order_date) AS rfm_recency,
      NTILE(5) OVER (ORDER BY count_order) AS rfm_frequency,
      NTILE(5) OVER (ORDER BY avg_amount) AS rfm_monetary
    FROM (
      SELECT
        fullVisitorId,
        MAX(date) AS last_order_date,
        COUNT(*) AS count_order,
        AVG(totals.totalTransactionRevenue)/1000000 AS avg_amount
      FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_20170*`
      WHERE
        _table_suffix BETWEEN "101"
        AND "801"
        AND totals.totalTransactionRevenue IS NOT NULL
      GROUP BY
        fullVisitorId )

Ответы [ 2 ]

0 голосов
/ 09 июля 2018

Ниже для стандартного SQL BigQuery и предполагается, что ваш первоначальный запрос работает для вас, SQL UDF NON_UNIFORM_BUCKET () выполняет свою работу за вас

#standard SQL    
CREATE TEMP FUNCTION NON_UNIFORM_BUCKET(i INT64) AS (
  CASE 
    WHEN i = 1 THEN 1
    WHEN i IN (2, 3) THEN 2
    WHEN i IN (4, 5, 6) THEN 3
    WHEN i = 7 THEN 4
    ELSE 5
  END
);
  SELECT
      fullVisitorId,
      NON_UNIFORM_BUCKET(NTILE(10) OVER (ORDER BY last_order_date)) AS rfm_recency,
      NON_UNIFORM_BUCKET(NTILE(10) OVER (ORDER BY count_order)) AS rfm_frequency,
      NON_UNIFORM_BUCKET(NTILE(10) OVER (ORDER BY avg_amount)) AS rfm_monetary
    FROM (
      SELECT
        fullVisitorId,
        MAX(date) AS last_order_date,
        COUNT(*) AS count_order,
        AVG(totals.totalTransactionRevenue)/1000000 AS avg_amount
      FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_20170*`
      WHERE
        _table_suffix BETWEEN "101"
        AND "801"
        AND totals.totalTransactionRevenue IS NOT NULL
      GROUP BY
        fullVisitorId )
0 голосов
/ 02 июля 2018

Вы можете использовать row_number() и count(*), чтобы определить свои собственные группы:

SELECT fullVisitorId,
       (CASE WHEN seqnum_r <= 0.1 * cnt THEN 1
             WHEN seqnum_r <= 0.3 * cnt THEN 2
             ELSE 3
        END) as bin_r,
       . . .               
FROM (SELECT fullVisitorId,
             MAX(date) AS last_order_date,
             COUNT(*) AS count_order,
             (AVG(totals.totalTransactionRevenue) / 1000000) AS avg_amount,
             COUNT(*) OVER () as cnt,
             ROW_NUMBER() OVER (ORDER BY MAX(date)) as seqnum_r,
             ROW_NUMBER() OVER (ORDER BY COUNT(*)) as seqnum_f,
             ROW_NUMBER() OVER (ORDER BY AVG(totals.totalTransactionRevenue)) as seqnum_m
      FROM `bigquery-public-data.google_analytics_sample.ga_sessions_20170*`
      WHERE _table_suffix BETWEEN "101" AND "801" AND
            totals.totalTransactionRevenue IS NOT NULL
      GROUP BY fullVisitorId
     ) rfm
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...