我可以减少这个查询吗?

Can I reduce this query?

我有一个 table 名字 likes,它存储了 post 的喜欢和不喜欢的详细信息。要显示 post 的总点赞数,我需要区分喜欢和不喜欢之间的差异。现在,我将点赞存储在类型为 bool 的名为 liked 的列中。这个想法是,如果喜欢则将其设置为 true,不喜欢则设置为 false。我的 table 看起来像这样,

| id | user_id | post_id | liked | 
| -- | ------- | ------- | ----- |
| 1  | 1       | 1       | true  |
| 2  | 7       | 1       | false |
| 3  | 12      | 1       | true  |

我用了SELECT liked, COUNT(*) FROM likes WHERE post_id=1 GROUP BY liked;,结果返回

| liked | count |
| ----- | ----- |
| TRUE  | 2     |
| FALSE | 1     |

我想了解这两者的区别。似乎找不到任何东西,所以我尝试了
SELECT SUM((SELECT COUNT(*) FROM likes WHERE post_id=1 AND liked = true) - (SELECT COUNT(*) FROM likes WHERE post_id=1 AND liked = false));

哪个returns我想要什么

| SUM |
| --- |
| 1   |

但我还是觉得这个查询不对。有没有更好的方法来编写这个查询?

一般的解决方案是分两步进行聚合:

select max(cnt) - min(cnt)
from
(
  select count(*) cnt FROM likes WHERE post_id=1 GROUP BY liked
) dt

在你的例子中,只有两个不同的值,你可以使用条件聚合:

select abs(count(*) filter (where c1 = true) - count(*) filter (where c1 = false))
from b
WHERE post_id=1 

这里有两个选项:

SELECT COUNT(*) FILTER (WHERE liked) - COUNT(*) FILTER (WHERE NOT liked)
FROM likes
WHERE post_id = 1;

SELECT SUM(CASE WHEN liked THEN 1 ELSE -1 END)
FROM likes
WHERE post_id = 1;