Как найти самую частую пару в SQL? - PullRequest
1 голос
/ 05 февраля 2020

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

Исходный набор данных

Эта таблица содержит потоковую активность пользователей c в определенный день. Я хочу выяснить, какая пара артистов была наиболее часто играемой в определенный день c. Ответ должен быть (Pink Floyd, Queen), потому что 3 пользователя слушали обоих исполнителей в один и тот же день. Как мне этого добиться?

Я начал с присоединения таблицы к себе, используя этот код:

With temp as (
select person_id, artist_name, count(*) as times_played from users where date_played = '2020-10-01' group by 1,2)
select a.person_id, a.artist_name, b.artist_name from temp a join temp b
On a.person_id = b.person_id and a.artist_name != b. artist_name;

В результате следует :

Я не конечно, с этой точки зрения, так что любая помощь будет полезна!

Ниже приведен код для создания таблицы в mySQL

create table users
(
  person_id       int,
  artist_name     varchar(255),
  date_played     date
);

insert into users
  (person_id, artist_name, date_played)
values
  (1, 'Pink Floyd', '2020-10-01'),
  (1, 'Led Zeppelin', '2020-10-01'),
  (1, 'Queen', '2020-10-01'),
  (1, 'Pink Floyd', '2020-10-01'),
  (2, 'Journey', '2020-10-01'),
  (2, 'Pink Floyd', '2020-10-01'),
  (2, 'Queen', '2020-10-01'),
  (2, 'Pink Floyd', '2020-10-01'),
  (3, 'Pink Floyd', '2020-10-01'),
  (3, 'Aerosmith', '2020-10-01'),
  (3, 'Queen', '2020-10-01'),
  (4, 'Pink Floyd', '2020-10-01'),
  (4, 'Led Zeppelin', '2020-10-01');

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Вот как я решил свой вопрос благодаря уловке, которую я нашел в коде, предоставленном Тимом Бигелайзеном в этом посте (u1.artist_name < u2.artist_name):

With temp AS (
    SELECT 
        person_id, 
        artist_name 
    FROM users 
    WHERE date_played = '2020-10-01' 
    GROUP BY 1,2
)
SELECT * 
FROM (

SELECT
    u1.artist_name AS artist1,
    u2.artist_name AS artist2,
    COUNT(*) AS times_played,
    RANK() OVER (ORDER BY COUNT(*) DESC) Rnk
FROM temp u1
JOIN temp u2
ON u1.artist_name < u2.artist_name AND u1.person_id = u2.person_id
GROUP by 1,2
) sub

WHERE Rnk = 1; 

0 голосов
/ 05 февраля 2020

Мы можем попробовать выполнить это требование с помощью самостоятельного соединения вместе с функцией RANK() analyti c:

WITH cte AS (
    SELECT
        u1.artist_name AS artist1,
        u2.artist_name AS artist2,
        RANK() OVER (ORDER BY COUNT(*) DESC) rnk
    FROM users u1
    INNER JOIN users u2
        ON u1.artist_name < u2.artist_name AND u1.person_id = u2.person_id
    WHERE
        u1.date_played = u2.date_played
    GROUP BY
        u1.artist_name,
        u2.artist_name
)

SELECT
    artist1,
    artist2
FROM cte
WHERE rnk = 1;
...