MySQL: есть ли способ использовать оконные функции вместо подзапросов, чтобы найти среднее число раз, когда действие выполняется для пользователя? - PullRequest
0 голосов
/ 31 января 2020

У меня есть таблица с именем log, которая записывает, когда пользователь выполняет одно из небольшого числа действий; давайте предположим, что это действия 1 и 2, и пользователи могут выбрать повторное выполнение этих действий. В таблице есть столбцы username, action_time, action_done.

Я хотел бы, чтобы набор результатов содержал столбец для действий, среднее число раз, когда это действие было выполнено (для каждого пользователя), и максимальное количество раз, когда любой пользователь выполнял это действие. Я смог выполнить sh это с помощью довольно неуклюжего подзапроса:

SELECT   
  DISTINCT(s.action) as "Action",  
  AVG(s.times_done) OVER (PARTITION BY s.action) as "Average Times Done",  
  MAX(s.times_done) OVER (PARTITION BY s.action) as "Max Times Done"  
FROM (
SELECT action, COUNT(action)  as times_done
FROM log
GROUP BY action, username 
) s;

У меня есть элементарное понимание оконных функций, но я не могу заставить работать подзапрос правильно используя COUNT в качестве оконной функции. Более того, я чувствую, что должен быть в состоянии выполнить sh намного проще, избегая подзапроса в целом. Например, если мой набор данных был:

------------------------------------------------------
|  username  |      action_time      |  action_done  |
======================================================
| first_user |  2020-01-30 13:01:23  |       1       |
| first_user |  2020-01-30 12:34:40  |       2       |
| first_user |  2020-01-30 12:34:56  |       2       |
| secnd_user |  2020-01-30 15:25:14  |       1       |
| secnd_user |  2020-01-30 15:25:00  |       2       |
| secnd_user |  2020-01-30 15:25:31  |       2       |
| secnd_user |  2020-01-30 15:26:02  |       2       |

, то я хотел бы получить следующий набор результатов:

------------------------------------------------------
|  Action  |  Average Times Done  |  Max Times Done  |
======================================================
|    1     |           1          |        1         |
|    2     |          2.5         |        3         |

Кто-нибудь может высказать некоторые предложения?

Редактировать : Позвольте мне немного объяснить данные и набор результатов. Я включил столбец даты и времени ISO не потому, что я ожидаю, что он будет иметь отношение к конечной цели, а потому, что я нашел данные более запутанными без них. Пользователи взаимодействуют с каким-либо веб-сайтом, а база данных хранит информацию о том, кто, что и когда делает.

Итак, first_user выполняет действие 1 один раз, действие 2 дважды. Затем second_user выполняет действие 1 один раз, действие 2 - 3 раза.

Следовательно, среднее число раз, когда мои два пользователя выполняли действие 1, составляет один раз: (1 + 1) / 2. Среднее количество раз, когда мои пользователи выполняли действие два, составляло 2,5 раза: (2 + 3) / 2.

Второе редактирование: Возможно, вызов действий 1 и 2 был непонятным выбором. На самом деле это больше похоже на то, что на этом сайте есть две кнопки, кнопка A и кнопка B, и пользователи нажимают на них. Я хотел бы знать, что среди всех пользователей люди, как правило, нажимали кнопку А от 5 до 6 раз, но чаще нажимали кнопку 6 или более раз, и поэтому было бы в среднем 5,72 нажатия на А. Возможно, один человек любит кнопку А больше, чем кто-либо другой, и они нажимают на нее 50 раз. Строка результата Action, Average Times Done, Max Times Done для button_A будет:

|  A  |   5.72   |    50   |

1 Ответ

0 голосов
/ 31 января 2020
WITH cte AS ( SELECT action_done,
                     username,
                     COUNT(action_done) cnt
              FROM actions
              GROUP BY action_done, username )
SELECT action_done `Action`,
       AVG(cnt) `Average Times Done`,
       MAX(cnt) `Max Times Done`
FROM cte
GROUP BY action_done;

скрипка

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