Postgres:根据结果加入两个查询和 select
Postgres: join two queries and select based on result
有一个社交网络,每个用户都可以转发另一个用户的帖子。每转发 10 次您的帖子,您将获得一份礼物。有两个表:gifts
和 repost_history
,请参见下面的方案。
问题: 如何编写一个查询来计算我需要为系统中的每个用户赠送多少礼物?
=========
= gifts =
=========
id // PK
user_id // id of user which received a gift
amount // amount of gifts (bonuses), may be + or -
type // type of a gift. The only type we're interested in is 'REPOST_TYPE'
==================
= repost_history =
==================
id // PK
user_id // id of a user which did repost
owner_id // id of a user whose post was reposted
查询算法:
1) 查找每个用户的总转发次数
SELECT owner_id, COUNT(owner_id) FROM repost_history GROUP BY owner_id;
2)求出每位用户的REPOST_TYPE
礼物总金额
SELECT user_id, COUNT(amount) FROM gifts WHERE type = 'REPOST_TYPE' GROUP BY user_id;
3) 根据owner_id = user_id
加入第一步和第二步
4) From (user_id, gift_to_grand_count) 基于第3步结果的结果集。其中 <gift_to_grand_count> = (<reposts_of_user> / 10) - <user_repost_gifts_amount>
我的解决方法: 1-3 步实施(不起作用,因为我不知道如何将子查询结果设置为变量)。如何让它工作并执行第 4 步?
(
SELECT owner_id, COUNT(owner_id) AS reposts_count
FROM reposts_history
GROUP BY owner_id
AS user_reposts
)
INNER JOIN (
SELECT user_id, COUNT(amount) AS gifts_count
FROM gifts
WHERE type = 'REPOST_GIFT'
GROUP BY user_id
AS user_gifts
)
ON user_reposts.owner_id = user_gifts.user_id
数据样本:
为简单起见,假设我们想在每 3 次转发(而不是每 10 次)时赠送一份礼物
gifts - 你可以看到 user_id=1
已获得 1 份 REPOST_TYPE
的礼物。我们对他花了多少礼物不感兴趣。
id | user_id | amount | type |
1 | 1 | 1 | 'REPOST_TYPE' |
2 | 1 | 2 | 'OTHER_TYPE' |
3 | 1 | -1 | 'REPOST_TYPE' |
4 | 2 | 1 | 'REPOST_TYPE' |
reposts_history - 您可以看到用户 owner_id=1
被其他用户转发了 6 次。
id | user_id | owner_id | another columns...
1 | 2 | 1 |
2 | 3 | 1 |
3 | 4 | 1 |
4 | 5 | 1 |
5 | 2 | 1 |
6 | 6 | 1 |
6 | 13 | 2 |
所以 user_id=1
应该被授予 <total_reposts> / 3 - <already_granted_gifts_amount> = 6 / 3 - 1 = 1
礼物。
我想为系统中的所有用户获取:
user_id | gifts_to_grant |
1 | 1 |
2 | 0 |
..........
您需要外部联接才能同时找到应得礼物但尚未收到礼物的用户:
select
b.ownerid as userid,
b.rebets_count,
b.rebets_count / 10 as gifts_expected,
coalesce(g.gifts_count, 0) as gifts_received,
b.rebets_count / 10 - coalesce(g.gifts_count, 0) as gifts_missing
from
(
select owner_id, count(*) as rebets_count
from bets
group by owner_id
) b
left join
(
select user_id, count(*) as gifts_count
from gifts
where type = 'REBET_GIFT'
group by user_id
) g on g.user_id = b.owner_id;
有一个社交网络,每个用户都可以转发另一个用户的帖子。每转发 10 次您的帖子,您将获得一份礼物。有两个表:gifts
和 repost_history
,请参见下面的方案。
问题: 如何编写一个查询来计算我需要为系统中的每个用户赠送多少礼物?
=========
= gifts =
=========
id // PK
user_id // id of user which received a gift
amount // amount of gifts (bonuses), may be + or -
type // type of a gift. The only type we're interested in is 'REPOST_TYPE'
==================
= repost_history =
==================
id // PK
user_id // id of a user which did repost
owner_id // id of a user whose post was reposted
查询算法:
1) 查找每个用户的总转发次数
SELECT owner_id, COUNT(owner_id) FROM repost_history GROUP BY owner_id;
2)求出每位用户的REPOST_TYPE
礼物总金额
SELECT user_id, COUNT(amount) FROM gifts WHERE type = 'REPOST_TYPE' GROUP BY user_id;
3) 根据owner_id = user_id
4) From (user_id, gift_to_grand_count) 基于第3步结果的结果集。其中 <gift_to_grand_count> = (<reposts_of_user> / 10) - <user_repost_gifts_amount>
我的解决方法: 1-3 步实施(不起作用,因为我不知道如何将子查询结果设置为变量)。如何让它工作并执行第 4 步?
(
SELECT owner_id, COUNT(owner_id) AS reposts_count
FROM reposts_history
GROUP BY owner_id
AS user_reposts
)
INNER JOIN (
SELECT user_id, COUNT(amount) AS gifts_count
FROM gifts
WHERE type = 'REPOST_GIFT'
GROUP BY user_id
AS user_gifts
)
ON user_reposts.owner_id = user_gifts.user_id
数据样本:
为简单起见,假设我们想在每 3 次转发(而不是每 10 次)时赠送一份礼物
gifts - 你可以看到 user_id=1
已获得 1 份 REPOST_TYPE
的礼物。我们对他花了多少礼物不感兴趣。
id | user_id | amount | type |
1 | 1 | 1 | 'REPOST_TYPE' |
2 | 1 | 2 | 'OTHER_TYPE' |
3 | 1 | -1 | 'REPOST_TYPE' |
4 | 2 | 1 | 'REPOST_TYPE' |
reposts_history - 您可以看到用户 owner_id=1
被其他用户转发了 6 次。
id | user_id | owner_id | another columns...
1 | 2 | 1 |
2 | 3 | 1 |
3 | 4 | 1 |
4 | 5 | 1 |
5 | 2 | 1 |
6 | 6 | 1 |
6 | 13 | 2 |
所以 user_id=1
应该被授予 <total_reposts> / 3 - <already_granted_gifts_amount> = 6 / 3 - 1 = 1
礼物。
我想为系统中的所有用户获取:
user_id | gifts_to_grant |
1 | 1 |
2 | 0 |
..........
您需要外部联接才能同时找到应得礼物但尚未收到礼物的用户:
select
b.ownerid as userid,
b.rebets_count,
b.rebets_count / 10 as gifts_expected,
coalesce(g.gifts_count, 0) as gifts_received,
b.rebets_count / 10 - coalesce(g.gifts_count, 0) as gifts_missing
from
(
select owner_id, count(*) as rebets_count
from bets
group by owner_id
) b
left join
(
select user_id, count(*) as gifts_count
from gifts
where type = 'REBET_GIFT'
group by user_id
) g on g.user_id = b.owner_id;