我可以减少这个查询吗?
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;
我有一个 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;