Как спрогнозировать отток для транзакций, сгруппированных по одному и тому же порядковому номеру заказа в Google BigQuery SQL? - PullRequest
0 голосов
/ 09 января 2020

Я новичок в SQL в BigQuery. Я пытаюсь предсказать статус клиента на основе их order_id и date_start.

Правила

  1. customer_status должно быть одинаковым для того же идентификатора order_id

  2. Customer_status должно быть спрогнозировано на основе следующего Order_ID ( Транзакция) или предыдущий Order_ID

это мой код

select week_start, t.account_id, t.order_id, date_start,date_ended,

from unnest(generate_date_array(date('2018-12-31'), date('2019-2-11'), interval 1 week) )  week_start cross join
     (select distinct account_id
      from t
     ) a left join
     t
     on t.account_id = a.account_id and
        t.reporting_week_start_date = week_start
order by  a.account_id,week_start

Вывод из моего кода

week_start | account_id  | order_id  | date_start   | date_ended   |
2018-12-31 |    1        |    1001   |   2019-01-01 |  2019-01-15  |
2019-01-07 |    1        |    1001   |   2019-01-01 |  2019-01-15  |
2019-01-14 |    1        |    1002   |   2019-01-15 |  2019-01-27  |
2019-01-21 |    1        |    1002   |   2019-01-15 |  2019-01-27  |
2019-01-28 |    1        |    1003   |   2019-01-29 |  2019-02-04  |

Желание Вывод

week_start | account_id  | order_id  | date_start   | date_ended   | Customer_Status
2018-12-31 |    1        |    1001   |   2019-01-01 |  2019-01-15  |  First Time
2019-01-07 |    1        |    1001   |   2019-01-01 |  2019-01-15  |  First Time
2019-01-14 |    1        |    1002   |   2019-01-15 |  2019-01-27  |  Recurring
2019-01-21 |    1        |    1002   |   2019-01-15 |  2019-01-27  |  Recurring
2019-01-28 |    1        |    1003   |   2019-01-29 |  2019-02-04  |  Churned

Как мне это сделать в Big Query SQL? Спасибо.

1 Ответ

0 голосов
/ 13 января 2020

Проанализировав ваше дело, я выяснил правила, которые вы могли бы использовать для классификации клиентов. Поскольку вы хотите классифицировать каждого клиента в BigQuery, все правила были жестко заданы.

Вы упомянули, что классификация должна основываться на следующем и предыдущем Order_id , но я также использовал поле account_id . По этой причине я использовал два метода LAG () и LEAD () .

Пример кода ниже должен быть включен в ваш текущий запрос, я использовал ваш текущий вывод в качестве моего источника ввода. Я следовал приведенному ниже алгоритму:

1) Классификация клиентов, впервые участвующих в программе. Итак, я создал временную таблицу new_c;

2) Классифицируйте постоянных клиентов, затем была создана временная таблица rec_ c;

3) Переработанные клиенты с последней временной таблицей churn_c;

4) J выкладывают все таблицы на основе на входе источника (ваш текущий выход) в фазе обрабатывалось дублированное состояние, как, например, когда у нас два статуса клиента «Первый раз» и т. д.

Ниже приведен код, обратите внимание что я использовал немного разные имена столбцов:

    #First selecting the new costumers and changing the namwes of some columns so we can use left join in the end
WITH
  new_c AS (
  SELECT
    _account_id__ AS acc,
    _order_id__ AS oo,
    week_start_ AS wk_nc,
    CASE
      WHEN ((LAG(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)IS NULL) AND (LAG(_order_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)IS NULL )) THEN 'First time'
      WHEN (LAG(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC) != _account_id__ ) THEN 'First time'
  END
    AS status
  FROM
    `test-proj-261014.sample.customer` ),

  #Now, we classify the customers who are Recurring
  rec_c AS (
  SELECT
    _account_id__ AS acc_rc,
    _order_id__ AS oo_rc,
    week_start_ AS wk_rc,
    CASE
      WHEN ((LAG(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)= _account_id__ ) AND (LAG(_order_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)!= _order_id__) AND (LEAD(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC) = _account_id__ ) ) THEN 'Recurring'
  END
    AS status_rc
  FROM
    `test-proj-261014.sample.customer` ),

  #Last, the Churned customers
  churn_c AS (
  SELECT
    _account_id__ AS acc_c,
    _order_id__ AS oo_c,
    week_start_ AS wk_ch,
    CASE
      WHEN ((LEAD(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)!= _account_id__ ) AND (LAG(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)= _account_id__ )) THEN 'Churned'
      WHEN ((LEAD(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC) IS NULL)
      AND (LAG(_account_id__) OVER (PARTITION BY _account_id__ ORDER BY _order_id__ ASC)= _account_id__ )) THEN 'Churned'
  END
    AS status_churn
  FROM
    `test-proj-261014.sample.customer` )

  #In the end, all the temporary tables are joined together and we handle same status customers.
SELECT
  week_start_,
  _account_id__,
  _order_id__,
  _date_start___,
  _date_ended___,
  CASE
    WHEN status IS NOT NULL THEN status
    WHEN (LAG(status) OVER (PARTITION BY acc ORDER BY oo ASC) ='First time'
    AND LAG(oo) OVER (PARTITION BY acc ORDER BY oo ASC)=oo)THEN 'First time'

    WHEN status_rc IS NOT NULL THEN status_rc
    WHEN (LAG(status_rc) OVER (PARTITION BY acc_rc ORDER BY oo_rc ASC) ='Recurring'
    AND LAG(oo_rc) OVER (PARTITION BY acc ORDER BY oo ASC)=oo_rc) THEN 'Recurring'

    WHEN churn_c IS NOT NULL THEN status_churn
    WHEN (LAG(status_churn) OVER (PARTITION BY acc_c ORDER BY oo_c ASC) ='Churned'
    AND LAG(oo_c) OVER (PARTITION BY acc ORDER BY oo ASC)=oo_c) THEN 'Churned'

END
  AS final_status
FROM
  `test-proj-261014.sample.customer`
INNER JOIN
  new_c
ON
  _account_id__ = ACC
  AND _order_id__ = OO
  AND week_start_ = wk_nc
INNER JOIN
  rec_c
ON
  _account_id__ = acc_rc
  AND _order_id__ = oo_rc
  AND week_start_ = wk_rc
INNER JOIN
  churn_c
ON
  _account_id__ = acc_c
  AND _order_id__ = oo_c
  AND week_start_ = wk_ch ;
...