【问题标题】:sql count() from multiple tables来自多个表的 sql count()
【发布时间】:2015-02-26 11:02:58
【问题描述】:

有这样的表格:

  1. 图片:

    wall_id|picture_id|user_id|likes
          1|         1|      1|    2
          1|         2|      1|    0
          2|         1|      1|    1
          2|         2|      2|    2
    

Pair (wall_id, picture_id) 是唯一的

  1. 喜欢的人:

    wall_id|picture_id|user_id
          1|         1|      3
          1|         1|      2
          2|         1|      2
          2|         2|      4
          2|         2|      3
    

我想得到类似的东西:

    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

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

【问题讨论】:

    标签: sql sqlite count


    【解决方案1】:

    Joins 很奇怪。当您有一个键并且多行在 both 两侧匹配时,您将获得更多您期望的行。解决方案是预先聚合每一侧的行。

    这对您的数据模型来说有点复杂,因为您需要 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;
    

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

    【讨论】:

      【解决方案2】:

      试试这个:

      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 中查看结果。

      【讨论】:

        【解决方案3】:

        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
        

        【讨论】:

        • 您的查询结果 this 与 OP 的预期输出不同。
        猜你喜欢
        • 1970-01-01
        • 2022-09-27
        • 2013-09-22
        • 2019-03-09
        • 2012-10-27
        • 1970-01-01
        • 2012-02-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多