Каков наилучший способ сделать этот запрос (SQL) - PullRequest
0 голосов
/ 09 апреля 2020

Мне нужно сделать запрос, но я не могу найти хороший способ сделать это эффективно.

Каждый раз, когда клиент слушает песню, одна строка регистрируется с его ключом и track_id, date .. ..

Я хочу проверить для каждого клиента, является ли трек, который он прослушал в прошлом месяце, новым (никогда не слушал до этого месяца)

Одна строка выглядит следующим образом:

key | track_id | date
asd | 12312    | 12/02/2020
fds | 12323    | 12/05/2020

et c

Я думаю, что могу что-то сделать с помощью оконных функций, но я не могу найти хороший способ сделать это.

Тогда мне также нужно получить 3 самых популярных песни из этого списка, которые я могу просто сделать с помощью оконной функции.

Если кто-то может мне помочь? Большое спасибо.

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Использовать функции агрегации и окна:

select key, count(*) as num_rows,
       count(*) as num_tracks,
       sum( case when first_yyyymm = yyyymm then 1 else 0 end) as num_new_tracks,
       sum( case when first_yyyymm < yyyymm then 1 else 0 end) as num_prev_tracks
from (select t.key, track_id, date_trunc('month', date) as yyyymm,
             min(date_trunc('month', date) ) over (partition by key, track_id) as first_yyyymm
      from t
      group by key, track_id, yyyymm
     ) t
where yyyymm >= date_trunc('month', current_date)
group by key
0 голосов
/ 14 апреля 2020

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

create table sandbox.songs 
(key varchar,
track_id number,
dt date);

insert into  sandbox.songs 
values
('asd', 12312, '12/02/2020'),
('fds', 12323, '12/05/2020'),
('asd', 11000, '04/05/2020'),
('fds', 92823, '04/07/2020'),
('asd', 11000, '3/05/2020'),
('fds', 12323, '12/05/2020'),
('asd', 92834, '3/05/2020');

ВОПРОС 1

select 
    key, 
    count(0), 
    sum(case when dt < current_date - 30 then 1 else 0 end) as older_than_30,
    sum(case when dt >= current_date - 30 then 1 else 0 end) as within_30    
from sandbox.songs group by key;

[введите описание изображения здесь] [1]

ВОПРОС 2

track_id, 
count(0) 
from sandbox.songs 
group by track_id 
order by count(0) desc 
limit 3;

[enter image description here][2]


  [1]: https://i.stack.imgur.com/CeDqw.png
  [2]: https://i.stack.imgur.com/sdKV0.png
...