2014-02-15 3 views
0

У меня есть две таблицы, lastfm_scrobbles и lastfm_annotations. Примеры данных:Выберите ежемесячные подсчеты данных по двум таблицам в mysql

mysql> select * from lastfm_scrobbles limit 5; 
+---------+---------+-----------+---------------------+ 
| user_id | item_id | artist_id | scrobble_time  | 
+---------+---------+-----------+---------------------+ 
| 1469 | 45651 |   1 | 2010-06-30 13:57:42 | 
| 1469 | 45651 |   1 | 2011-03-28 15:43:37 | 
| 6872 | 45653 |   1 | 2013-08-03 15:07:44 | 
| 7044 | 1370 |   1 | 2007-03-26 17:07:26 | 
| 7044 | 1370 |   1 | 2007-08-24 18:41:35 | 
+---------+---------+-----------+---------------------+ 

mysql> select * from lastfm_annotations limit 5; 
+---------+---------+-----------+--------+------------+ 
| user_id | item_id | artist_id | tag_id | tag_month | 
+---------+---------+-----------+--------+------------+ 
|  121 | 1330412 | 1330412 | 475 | 2006-12-01 | 
|  121 | 1330412 | 1330412 | 517 | 2006-12-01 | 
|  121 | 1330412 | 1330412 | 7280 | 2006-12-01 | 
|  121 | 1330412 | 1330412 | 21384 | 2006-12-01 | 
|  121 | 1330412 | 1330412 | 27872 | 2006-12-01 | 
+---------+---------+-----------+--------+------------+ 

Кроме того, у меня есть таблица пользовательских данных (lastfm_users). Детали этого не важны, но значение имеет то, что запрос:

select user_id from lastfm_users where scrobbles_recorded==1; 

Возвращает пользователь я небезразличен для целей этого вопроса.

Хорошо, с этой преамбулой: мне нужен запрос, который даст мне, для этих пользователей, общее количество записей, которые они имеют в обеих таблицах scrobbles и annotations за каждый месяц. Другими словами, результат должен выглядеть примерно так:

user_id y  m  scrobble_count anno_count 
123  2006 3  100    50 
456  2008 11  321    10 
... and so on 

Имеют смысл? Я считаю, что запрос я хочу это сочетание следующих условий:

select year(tag_month) as y, month(tag_month) as m, count(*) as anno_count 
    from lastfm_annotations where user_id in (select user_id from 
     lastfm_users where scrobbles_recorded=1) 
    group by user_id, year(tag_month), month(tag_month); 


select year(scrobble_time) as y, month(scrobble_time) as m, count(*) as scrobble_count 
    from lastfm_scrobbles where user_id in (select user_id from 
     lastfm_users where scrobbles_recorded=1) 
    group by user_id, year(scrobble_time), month(scrobble_time); 

Но я не уверен в правильном пути для создания присоединиться запрос, чтобы получить результат я хочу. Предложения?

ответ

0

Вы можете попробовать

select user_id, y, m, 
     coalesce(sum(case when source = 1 then total end), 0) anno_count, 
     coalesce(sum(case when source = 2 then total end), 0) scrobble_count 
    from 
(
    select 1 source, a.user_id, year(tag_month) y, month(tag_month) m, count(*) total 
    from lastfm_annotations a join lastfm_users u 
     on a.user_id = u.user_id 
    where u.scrobbles_recorded = 1 
    group by user_id, year(tag_month), month(tag_month) 
    union all 
    select 2 source, s.user_id, year(scrobble_time), month(scrobble_time), count(*) 
    from lastfm_scrobbles s join lastfm_users u 
     on s.user_id = u.user_id 
    where u.scrobbles_recorded = 1 
    group by user_id, year(scrobble_time), month(scrobble_time) 
) q 
group by user_id, y, m 

или просто

select user_id, y, m, 
     sum(case when source = 1 then 1 else 0 end) anno_count, 
     sum(case when source = 2 then 1 else 0 end) scrobble_count 
    from 
(
    select 1 source, a.user_id, year(tag_month) y, month(tag_month) m 
    from lastfm_annotations a join lastfm_users u 
     on a.user_id = u.user_id 
    where u.scrobbles_recorded = 1 
    union all 
    select 2 source, s.user_id, year(scrobble_time), month(scrobble_time) 
    from lastfm_scrobbles s join lastfm_users u 
     on s.user_id = u.user_id 
    where u.scrobbles_recorded = 1 
) q 
group by user_id, y, m; 

Вот SQLFiddle демо

+0

Спасибо! Запустив их сейчас, чтобы проверить, работают ли они над моими данными и примут, как только это будет сделано. В то же время, не могли бы вы немного разобраться в двух методах? Какой из них предпочтительнее и почему? – moustachio

+0

4 часа и запрос (вторая версия) все еще запущен ... Мне интересно, может ли только это сделать итеративный процесс на данном этапе быстрее. – moustachio

+0

Наиболее вероятная причина этого недооценивается. Запустить 'EXPLAIN ' – peterm

Смежные вопросы