как узнать разницу во времени (в день) для каждой транзакции для каждого пользователя, используя mysql - PullRequest
1 голос
/ 09 марта 2020

У меня есть такая таблица:

CREATE TABLE test (
  ID SERIAL PRIMARY KEY,
  user_id INT,
  createdAt DATE,
  status_id INT
);

INSERT INTO test VALUES
  (1, 12, '2020-01-01', 4),
  (2, 12, '2020-01-03', 7),
  (3, 12, '2020-01-06', 7),
  (4, 13, '2020-01-02', 5),
  (5, 13, '2020-01-03', 6),
  (6, 14, '2020-03-03', 8),
  (7, 13, '2020-03-04', 4),
  (8, 15, '2020-04-04', 7),
  (9, 14, '2020-03-02', 6),
  (10, 14, '2020-03-10', 5),
  (11, 13, '2020-04-10', 8);

это моя скрипка

В этой таблице id для идентификатора каждой транзакции, user_id был пользователем, createdAt был датой совершения транзакции, а status_id был статусом для каждой транзакции (в данном случае status_id 4, 5, 6, 8 - подтвержденная транзакция)

Я хочу узнать максимальный, минимальный, средний день для каждой транзакции для каждого пользователя, который совершает транзакцию между 2020-02-01 и 2020-04-01 с> 1 транзакцией, утвержденной на этот период

Это мой запрос:

SELECT MIN(diff) AS `MIN`, MAX(diff) AS `MAX`, SUM(diff) / COUNT(DISTINCT user_id) AS `AVG`
FROM (
  SELECT ID, user_id, DATEDIFF((SELECT t2.createdAt FROM test t2 WHERE t2.user_id = t1.user_id AND t1.createdAt <= t2.createdAt AND t2.id <> t1.id LIMIT 1), t1.createdAt) AS diff
  FROM test t1
  where 
  status_id in (4, 5, 6, 8)
  HAVING SUM(t1.user_id BETWEEN '2020-02-01' AND '2020-04-01')
                  AND SUM(t1.user_id >= '2020-02-01') > 1 

) DiffTable
WHERE diff IS NOT NULL

, но сказано:

В агрегированном запросе без GROUP BY выражение # 1 списка SELECT содержит неагрегированный столбец 'fiddle_KDQIQDMUZEIOVXFHRZPY.t1. Я БЫ'; это несовместимо с sql_mode = only_full_group_by

что мне делать?

это моя скрипка

ожидаемый результат

+-----+-----+---------+
| MAX | MIN | AVERAGE |
+-----+-----+---------+
|  36 |   1 |      22 |
+-----+-----+---------+

объяснение:

- the user_id who have approval transaction on 2020-02-01 until 2020-04-01 and user_id who have transaction more than 1 are user_id 13 & 14
- the maximum of different day on 2020-02-01 until 2020-04-01 are user_id 13 which the different day for each transaction happen in 2020-03-04 and doing next transaction again in 2020-04-10
- the minimum day of different day of each transaction are user_id 14 who doing transaction on 2020-03-02 and next transaction 2020-03-03
- average are 22 days (sum of different day on user_Id 13 & 14 / amount of user_id who fit on this condition) 

1 Ответ

1 голос
/ 09 марта 2020

Вам нужно выполнить GROUP вне вашего подзапроса; Подзапрос должен использоваться только для ограничения выбранных транзакций теми, которые имеют желаемое значение status_id и даты в требуемом диапазоне. Затем вы можете выбрать пользователей с более чем одной транзакцией за период во внешнем запросе:

SELECT user_id,
       COUNT(*) AS transactions, 
       MIN(diff) AS `MIN`, 
       MAX(diff) AS `MAX`, 
       SUM(diff) / COUNT(diff) AS `AVG`
FROM (
  SELECT user_id, DATEDIFF((SELECT MIN(t2.createdAt)
                            FROM test t2
                            WHERE t2.user_id = t1.user_id
                              AND t1.createdAt < t2.createdAt
                              AND t2.status_id in (4, 5, 6, 8)
                            ), t1.createdAt) AS diff
  FROM test t1
  WHERE status_id in (4, 5, 6, 8)
    AND createdAt BETWEEN '2020-02-01' AND '2020-04-01'
) DiffTable
WHERE diff IS NOT NULL
GROUP BY user_id
HAVING COUNT(*) > 1

Вывод (для вашей скрипки):

user_id     transactions    MIN     MAX     AVG
14          2               1       7       4.0000

Демонстрация на dbfiddle

Если вы хотите, чтобы значения основывались на всех транзакциях, которые произошли за этот период, а не на user_id, вы можете просто удалить предложения GROUP BY и HAVING:

SELECT COUNT(*) AS transactions, 
       MIN(diff) AS `MIN`, 
       MAX(diff) AS `MAX`, 
       SUM(diff) / COUNT(diff) AS `AVG`
FROM (
  SELECT user_id, DATEDIFF((SELECT MIN(t2.createdAt)
                            FROM test t2
                            WHERE t2.user_id = t1.user_id
                              AND t1.createdAt < t2.createdAt
                              AND t2.status_id in (4, 5, 6, 8)
                            ), t1.createdAt) AS diff
  FROM test t1
  WHERE status_id in (4, 5, 6, 8)
    AND createdAt BETWEEN '2020-02-01' AND '2020-04-01'
) DiffTable
WHERE diff IS NOT NULL

Вывод:

transactions    MIN     MAX     AVG
3               1       37      15.0000

Демонстрация на dbfiddle

Обратите внимание, что в * 1028 есть пара проблем с существующим подзапросом * вычисление: LIMIT без ORDER BY не гарантирует ожидаемых результатов, и на status_id нет условий. Я исправил обе эти проблемы в моих обновленных запросах.

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