2012-12-14 76 views
-1

我有一个包含多个内容类型和用户的数据库,以及一个包含likes的独立数据库。我试图找出哪些用户收到了他们最喜欢的任何的内容,无论是哪种类型。使用GROUP BY和ORDER BY与多个INNER JOIN

我已经能够找出查找特定内容类型找到最喜欢的用户的查询,但与任何内容类型被证明是有点困难。

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

以下是我一直在创建查询时所做的工作......我非常确定这是不正确的!

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; 

有没有人请给我一个提示或指向正确的方向?我觉得我正在接近...

谢谢!

+1

为什么你的名字与同标号的三个不同的瓦尔? – Rubens

+0

您不应该选择不在您的聚合中的列。 – Kermit

+0

@njk你是什么意思? –

回答

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 
+0

我已添加查询。 – Barmar

+0

这指出了您的数据库设计可能存在的问题。如果有关于文档的所有类型不可知信息(例如作者)的单个表,并且引用特定于类型的表,那将会更好。 – Barmar

+0

当我尝试使用您的示例运行它时,出现:ERROR 1052(23000):字段列表中的列'user_id'不明确。值得注意的是,我也在类似的表中有一个user_id字段。 –

1

它,如果你想拥有与上市最喜欢的对象,或者你是否正在寻找具有分布在其所有的内容最全面喜欢的用户的用户目前尚不清楚。

考虑一个用户只有一张拥有1000个喜欢的照片,如果该用户在总共100张照片,用户总数为100张照片,视频和帖子的平均喜欢数为20的用户之前列出, 50?

这些是两个不同的查询。

现在,我将假设你想要找到的是“最喜欢的”项目,然后找出哪些用户是由哪些用户创建/创作的。要找到20个“最喜欢”的项目,这是非常简单的寻找一种“obj_id” S拥有最喜欢...

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 

我假设(基于原始查询),并没有一个明确的方案和样本数据,likes表中的obj_id的值引用其他表中的单个对象的值id ...即,obj_id值不会出现在photosvideos表中。 (否则,你可能有一列的地方旁边obj_id告诉你obj_id被引用的表。)

我们使用以前的查询作为内嵌视图(MySQL调用它派生表),并给它一个方便的“ml”别名(最喜欢),我们将对每个目标对象表(照片,视频,帖子)进行左连接,找出它是什么类型的项目,以及谁是用户/创作者/作者是。

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列是NOT NULL,且creator_id from the videos`表NOT 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