来自多个表的sql count()

时间:2015-02-26 11:02:58

标签: sql sqlite count

有这样的表格:

  1. 图片:

    wall_id|picture_id|user_id|likes
          1|         1|      1|    2
          1|         2|      1|    0
          2|         1|      1|    1
          2|         2|      2|    2
    
  2. 配对(wall_id,picture_id)是唯一的

    1. likers:

      wall_id|picture_id|user_id
            1|         1|      3
            1|         1|      2
            2|         1|      2
            2|         2|      4
            2|         2|      3
      
    2. 我希望得到类似的东西:

          user_id|pictures_count|likes_count|likers_count
                1|             3|          3|           2
                2|             1|          2|           2
      

      我试过了:

      select p.user_id as user_id, 
          count(p.user_id) as pictures_count, 
          sum(p.likes) as likes_count, 
          count(distinct l.user_id) as likers_count
       from pictures p
       left join likers l on p.wall_id = l.wall_id 
                             and p.picture_id = l.picture_id
       group by p.user_id
      

      select pictures.user_id, count(pictures.user_id) as pictures_count,
           sum(pictures.likes) as likes_count, 
          count(distinct likers.user_id) as likers_count 
      from pictures, likers 
      where pictures.picture_id = likers.picture_id 
          and pictures.user_id = likers.user_id 
      group by pictures.user_id
      

      但我得到了这样的结果:

          user_id|pictures_count|likes_count|likers_count
                1|             4|          6|           2
                2|             2|          4|           2
      

      我该怎么做才能获得正确的结果?

3 个答案:

答案 0 :(得分:1)

Join是好奇的事情。当您有一个键并且两个侧的多个行匹配时,您将获得更多您期望的行。解决方案是预先聚合每一侧的行。

这对您的数据模型来说有点复杂,因为您需要join来查找likes表的用户ID。

 select p.user_id as user_id, p.pictures_count, p.likes_count, l.likers_count
 from (select p.user_id, count(*) as pictures_count, sum(likes) as likes_count
       from pictures p
       group by p.user_id
      ) p left join
      (select p.user_id, count(distinct l.user_id) as likers_count
       from pictures p left join
            likers l
            on p.wall_id = l.wall_id and p.picture_id = l.picture_id
       group by p.user_id
      ) l
      on p.user_id = l.user_id;

请注意,由于聚合是在子查询中完成的,因此在外部查询中不再需要它。

答案 1 :(得分:0)

join可能会导致重复行。您可以在加入之前应用聚合。

select  *
from    (
        select  wall_id
        ,       sum(likes) as likes_count
        ,       count(*) as picture_count
        from    pictures
        group by
                wall_id
        ) as pictures
left join
        (
        select  wall_id
        ,       count(distinct user_id) as likers_count
        from    likers
        group by
                wall_id
        ) as likes 
on      pictures.wall_id = likes.wall_id

答案 2 :(得分:0)

试试这个:

SELECT T1.user_id,T1.pictures_count,T1.likes_count,T2.likers_count FROM
(select p.user_id,
       count(*) AS pictures_count,
       SUM(p.likes) as likes_count
from pictures p 
group by p.user_id) T1 JOIN

(select p.user_id,count(distinct l.user_id) as likers_count
from pictures p join
     likers l on p.wall_id = l.wall_id and p.picture_id = l.picture_id
group by p.user_id) T2 on T1.user_id=T2.user_id

结果:

USER_ID PICTURES_COUNT  LIKES_COUNT LIKERS_COUNT
1       3               3           2
2       1               2           2

请参阅SQL Fiddle中的结果。