2

对不起,笨拙的标题。一个例子将解释。

假设我有一个喜欢表,每个喜欢都有一个条目

user_id  |  liked_id
--------------------
   1     |     a
   2     |     a
   1     |     b
   2     |     c

表示用户1喜欢项目ab,并且用户2喜欢项目ac

要获得每个项目的总喜欢数,我可以这样做:

SELECT liked_id, COUNT(*)
  FROM likes
  GROUP BY liked_id

但是,有没有一种好方法可以做到这一点,但仅限于特定用户喜欢的项目?因此,例如,查询 user 1,我想要的结果是:

liked_id |  count
------------------
   a     |    2
   b     |    1

因为用户1喜欢项目ab,但不是c

我能想到的最好的是一个JOININ带有一个子选择:

SELECT l.liked_id, count(*)
  FROM likes l
    JOIN (
      SELECT liked_id
        FROM likes
        WHERE user_id = 1
      ) l2
      ON l.liked_id=l2.liked_id
  GROUP BY l.liked_id;

聚合时有没有更好的方法来汇总?我觉得我可能会做一些HAVING诡计,但也许不会,而且它可能是一个较慢的解决方案。

编辑:我正在使用 Postgres,如果标签没有说清楚的话。

编辑:感谢所有答案,当我问这个问题时,我接受了我认为最好和最快的答案 - 应该很明显,真的,但我给了每个人一个 +1。

我应该提到我需要从 likes 表中的条目中获取另一条数据,以便稍后订购。子选择将执行此操作,因为接受的答案将在SELECTGROUP BY部分中添加一个附加条目。这将教会我为一个 SO 问题过度简化一些东西......谢谢!

4

4 回答 4

2

您可以尝试以下方法:

SELECT liked_id, COUNT(*)
  FROM likes
 GROUP BY liked_id
HAVING count(case when user_id = 1 then 1 end) > 0;

count(case when user_id = 1 then 1 end)user_id = 1会计算喜欢了多少次liked_id

此查询将在一次完整扫描中获得结果。它会比 2 次完整扫描快,但可能比 2 次索引扫描慢(如果您在liked_id和上有索引user_id)。

于 2013-08-13T17:55:05.797 回答
1

使用存在

SELECT  L.LIKED_ID
        ,COUNT(L.USER_ID) AS USER_COUNT
FROM    LIKES L
WHERE   EXISTS (SELECT  1 
                FROM    LIKES L2 
                WHERE   L2.LIKED_ID = L.LIKED_ID 
                AND L2.USER_ID = 1
                )
GROUP BY 
        L.LIKED_ID
于 2013-08-13T17:44:37.177 回答
1

这应该有效,根据我的理解,您需要获取count仅被特定人喜欢的喜欢项目user

SELECT 
  liked_id, 
  COUNT(*)
FROM 
  likes l
WHERE
  EXISTS ( SELECT 1 FROM likes WHERE user_id = 1 AND like_id = l.id )
GROUP BY 
  liked_id
于 2013-08-13T17:55:13.010 回答
1

当然:将表加入自身:

SELECT t1.liked_id, COUNT(*)
FROM likes t1
JOIN likes t2 on t2.liked_id = t1.liked_id
WHERE t1.user_id = 1
GROUP BY t1.liked_id

这不仅是一种优雅的编码方式,而且性能最好,只要有一个liked_id用于连接性能的索引和一个user_id用于查找性能的索引。

于 2013-08-13T17:56:47.063 回答