Как сравнить внутри раздела все возможные значения в MySql? - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь сравнить значения для каждого пользователя для каждой транзакции продавца. Вот пример входной таблицы:

user_id|retailer_id|amount_spent
1      |2          |30
1      |2          |10
1      |2          |28

Теперь я хочу сравнить для каждого отдельного пользователя одного и того же продавца, если потраченная сумма была в пределах 30% во всех покупках. Допустим, что сумма, потраченная на первую и вторую транзакцию, составляет 67% (30 и 10 долларов), что превышает 30% пороговое значение. Тем не менее, третий ряд с потраченными 28 $ находится в пределах 30% отклонения по сравнению с 30 $ из первого ряда. Таким образом, эти две транзакции будут соответствовать критериям, то есть сравнение строки 1 и строки 3.

Текущий запрос:

   select distinct a.customer_id, a.purchase_date 

from 
(
select 
  customer_id,
  retailer,
  purchase_date,
  purchase_amount,
  Lag(purchase_amount) over (partition by customer_id,retailer) as previous_amt

  from tbl
)a 

where abs(a.purchase_amount-a.previous_amt)/a.purchase_amount <=0.3

Outout даст мне пустые строки, поскольку он сравнивает суммы последовательных транзакций , Однако не учитывается, что строка 1 и строка 3 удовлетворяют критериям, и, следовательно, будут возвращены эти 2 строки.

Как мне настроить свой запрос отсюда?

1 Ответ

0 голосов
/ 02 мая 2020

Рассмотрим следующее ...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,user_id INT NOT NULL 
,retailer_id INT NOT NULL
,amount_spent INT NOT NULL
);

INSERT INTO my_table (user_id,retailer_id,amount_spent) VALUES
(1,2,30),
(1,2,10),
(1,2,28),
(1,3,10),
(1,3,40),
(2,1,20);

Следующий запрос покажет нам все строки без какой-либо другой комбинации (user_id, retailer) в пределах 30% от другой (моя арифметика c или логи *) 1010 * может быть слегка искажен, но, надеюсь, вы поняли идею) ...

SELECT a.*
  FROM my_table a
  LEFT 
  JOIN 
     ( SELECT y.*
         FROM my_table x
         JOIN my_table y 
           ON y.id <> x.id
          AND y.user_id = x.user_id
          AND y.retailer_id = x.retailer_id
          AND y.amount_spent BETWEEN x.amount_spent * 0.3 AND x.amount_spent * 1.3
     ) b
    ON b.id = a.id
 WHERE b.id IS NULL;

   +----+---------+-------------+--------------+
   | id | user_id | retailer_id | amount_spent |
   +----+---------+-------------+--------------+
   |  4 |       1 |           3 |           10 |
   |  5 |       1 |           3 |           40 |
   |  6 |       2 |           1 |           20 |
   +----+---------+-------------+--------------+

При необходимости, мы можем дополнительно уточнить это следующим образом

 SELECT a.user_id
      , a.retailer_id
   FROM my_table a
   LEFT 
   JOIN 
      ( SELECT y.*
          FROM my_table x
          JOIN my_table y 
            ON y.id <> x.id
           AND y.user_id = x.user_id
           AND y.retailer_id = x.retailer_id
           AND y.amount_spent BETWEEN x.amount_spent * 0.3 AND x.amount_spent * 1.3
      ) b
     ON b.id = a.id
  WHERE b.id IS NULL
  GROUP 
     BY a.user_id
      , a.retailer_id 
 HAVING COUNT(*) > 1;

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