选择mysql中两个表的每月数据计数

时间:2014-02-15 21:50:27

标签: mysql sql

我有两个表,lastfm_scrobbles和lastfm_annotations。示例数据:

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);

但我不确定生成连接查询以获得我想要的结果的正确方法。建议?

1 个答案:

答案 0 :(得分: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 演示