MySQL Query для RFM-анализа - PullRequest
       9

MySQL Query для RFM-анализа

0 голосов
/ 18 октября 2019

У меня есть таблица с данными пользователя / заказа для анализа RFM. Пример:

+------+---------+--------+------------+
| id_o | user_id | price  | o_date     |
+---------+---------+--------+---------+
| 4491 |  544    | 100.00 | 2016-01-01 |
| 4494 |  642    | 200.00 | 2016-03-01 |
| 4497 |  596    |  50.00 | 2017-01-10 |
+---------+---------+--------+---------+

Я пытаюсь написать запрос, который выберет и сгруппирует пользователей, а также сумму, которую они потратили, и классифицирует их по RFM. Пока у меня есть:

SELECT user_id, id_o, price,
CASE WHEN price < 100 THEN '3'
     WHEN price >= 100 AND price < 500 THEN '2'
     ELSE '3'
END AS M,

CASE WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) < 30 THEN '1'
     WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) >= 30 AND
          TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) < 60 THEN '2'
     ELSE '3'
END AS R

FROM orders;

Этот запрос дает таблицу каждого заказа, сумму, потраченную на него, и отмеченные измерения R и M. Однако мне также нужно добавить измерение F, которое можно сделать как количество заказов на пользователя. Я попытался добавить еще один оператор CASE к запросу и группировать по user_id, поэтому он выглядит так:

SELECT user_id, SUM(price),
CASE WHEN price < 100 THEN '3'
     WHEN price >= 100 AND price < 500 THEN '2'
     ELSE '3'
END AS M,

CASE WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) < 30 THEN '1'
     WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2018-01-01')) >= 30 AND
          TIMESTAMPDIFF(DAY, o_date, DATE('2018-01-01')) < 60 THEN '2'
     ELSE '3'
END AS R,

CASE WHEN COUNT(id_o) > 20 THEN '1'
     WHEN COUNT(id_o) > 10 AND COUNT(id_o) <= 20 THEN '2'
     ELSE '3'
END AS F

FROM orders GROUP BY user_id;

Однако это не работает. Любой совет, как это исправить или что мне не хватает, был бы очень полезен. Является ли CASE даже подходящим инструментом для такого рода задач?

1 Ответ

0 голосов
/ 19 октября 2019

Я превратил существующий рабочий запрос во вложенный запрос, поместил поверх него дополнительный оператор CASE и добавил предложение GROUP BY. Это дало мне:

SELECT user_id, SUM(price) AS 'Total Sum', R, M, COUNT(Orders.id_o),
  CASE WHEN COUNT(Orders.id_o) < 2 THEN "3"
       WHEN COUNT(Orders.id_o) >=2 AND COUNT(id_o) <4 THEN "2"
       ELSE "1" 
  END AS F
FROM 
(SELECT user_id, id_o, price,
CASE WHEN price < 100 THEN '3'
     WHEN price >= 100 AND price < 500 THEN '2'
     ELSE '3'
END AS M,

CASE WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) < 30 THEN '1'
     WHEN TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) >= 30 AND
          TIMESTAMPDIFF(DAY, o_date, DATE('2019-01-01')) < 60 THEN '2'
     ELSE '3'
END AS R

FROM orders) AS Orders
GROUP BY user_id;

Возвращает таблицу, подобную следующей (LIMIT 3):

+---------+-----------+------+---+--------------------+---+
| user_id | Total Sum | R    | M | COUNT(Orders.id_o) | F |
+---------+-----------+------+---+--------------------+---+
|       0 |    400.00 | 3    | 2 |                  1 | 3 |
|       1 |     90.00 | 3    | 3 |                  2 | 2 |
|      76 |     80.00 | 3    | 3 |                  2 | 2 |
+---------+-----------+------+---+--------------------+---+

Надеюсь, это будет полезно и другим.

...