使用GROUP BY和ORDER BY与多个INNER JOINS

时间:2012-12-14 00:10:41

标签: mysql sql

我有一个包含多种内容类型和用户的数据库,以及一个包含喜欢的单独数据库。我试图找出哪些用户对其内容的任何获得了最多的喜欢,无论其类型如何。

我已经能够找出通过特定内容类型查找最喜欢的用户的查询,但使用任何内容类型的情况证明有点困难。

值得注意的是,此数据库中有数百万条记录。

这是我在创建查询时所做的工作......我很确定这不正确!

SELECT picture.user_id, video.creator_id, post.author_id
FROM likes_service.likes
INNER JOIN prod.pictures picture ON likes.obj_id = picture.id
INNER JOIN prod.videos video ON likes.obj_id = video.id
INNER JOIN prod.posts post ON likes.obj_id = post.id
GROUP BY picture.user_id, video.creator_id, post.author_id
ORDER BY COUNT(picture.user_id), COUNT(video.creator_id), COUNT(post.author_id) DESC
LIMIT 20;

有人可以给我一些提示或指出我正确的方向吗?我觉得我越来越近了......

谢谢!

2 个答案:

答案 0 :(得分:2)

我认为你想要一个UNION,而不是一个多方式的JOIN。

select objects.user_id user_id, sum(likes.like_count) like_count
from (
    select user_id, id
    from prod.pictures
    union all
    select creator_id, id
    from prod.videos
    union all
    select author_id, id
    from prod.posts) objects
join (select obj_id, count(*) likes_count
      from likes_service.likes
      group by obj_id) likes on likes.obj_id = objects.id
group by user_id
order by like_count desc

答案 1 :(得分:1)

目前尚不清楚您是否希望列出具有最多喜欢对象的用户,或者您是否正在寻找具有遍及其所有内容的最多整体喜欢的用户。

如果用户只有一张拥有1,000张喜欢的照片的用户,那么该用户是否应该在用户总共有100张照片,视频和帖子之前列出,平均数量为20,最高喜欢数量为50 ?

这是两个不同的查询。

现在,我将假设你想要找到的是“最喜欢”的项目,然后找出每个用户创建/创作的用户。要找到20个“最喜欢”的项目,找到“obj_id”最喜欢的项目非常简单明了...

SELECT l.obj_id
     , COUNT(1) AS like_count
  FROM likes_service.likes l
 GROUP BY l.obj_id
ORDER BY like_count DESC
LIMIT 0,20

我假设(基于您的原始查询),并且缺少架构和示例数据,obj_id表中likes的值引用了id的值{其中一个表中的单个对象...也就是说,obj_idphotos表中都不会显示videos值。 (否则,您可能在obj_id旁边的某个位置有一个列,告诉您obj_id引用了哪个表。)

我们使用之前的查询作为内联视图(MySQL将其称为派生表),并为其提供方便的别名“ml”(最喜欢),我们将对每个目标对象执行LEFT JOIN表格(照片,视频,帖子),以确定它是什么类型的项目,以及用户/创作者/作者是谁。

SELECT ml.obj_id
     , ml.like_count
     , p.user_id
     , v.creator_id
     , t.author_id
  FROM ( SELECT l.obj_id
              , COUNT(1) AS like_count
           FROM likes_service.likes l
          GROUP BY l.obj_id
          ORDER BY like_count DESC
          LIMIT 0,20
       ) ml
  LEFT
  JOIN prod.pictures p
    ON p.id = ml.obj_id
  LEFT
  JOIN prod.videos v
    ON v.id = ml.obj_id
  LEFT
  JOIN prod.videos v
    ON v.id = ml.obj_id
  LEFT
  JOIN prod.posts t
    ON t.id = ml.obj_id
 ORDER BY ml.like_count DESC

假设照片表中的user_id列不是NULL,而creator_id from the videos`表格不是NULL ...

然后你可以确定在哪个表中找到了obj_id。即如果user_id列不为空,你知道它来自照片表,如果creator_id不为空,你知道它来自视频表。

您可以在最外层的选择中添加一些表达式来解密...

SELECT CASE WHEN p.user_id    IS NOT NULL THEN 'photo'
            WHEN v.creator_id IS NOT NULL THEN 'video'
            WHEN t.author_ID  IS NOT NULL THEN 'post'
       END AS obj_type
     , CASE WHEN p.user_id    IS NOT NULL THEN p.user_id
            WHEN v.creator_id IS NOT NULL THEN v.creator_id
            WHEN t.author_id  IS NOT NULL THEN t.author_id
       END AS user_id
     , l.obj_id