在我的程序中,用户可以通过在该场所执行签到操作来在该场所赚取积分。
然后,他们可以使用这些积分在该地点兑换奖励。积分不能在不同地点共享。
我有下表:
用户
场地
check_ins
奖励
奖励兑换
我可以像这样计算用户在场所的总分:
select venue_id, sum(points) as total_points
from check_ins
WHERE user_id = 109
group by venue_id, user_id;
我可以像这样计算场地兑换的积分数:
select venue_id, sum(points) as points_redeemed
from reward_redemptions
JOIN rewards on reward_redemptions.reward_id = rewards.id
GROUP BY venue_id;
然后,我可以使用一种编程语言(例如PHP)减去每个场地的剩余点数。
但是,我想使用SQL来做到这一点(理想情况是在1个查询中,以减少在查询之间更改数据的机会,使代码更简单,并可能提高性能)。理想的最终结果是:
venue_id total_points points_redeemed points_remaining
#5 10 2 8
#15 25 10 15
#189 150 20 130
所以我的问题是:
答案 0 :(得分:1)
您可以使用union all
和group by
。这是有关地点和地点的查询:
select venue_id, sum(total_points) as total_points,
sum(points_redeemed) as points_redeemed
from ((select venue_id, sum(points) as total_points, 0 as points_redeemed
from check_ins
group by venue_id
)
union all
(select venue_id, 0 as total_points, sum(points) as points_redeemed
from reward_redemptions rr join
rewards r
on rr.reward_id = r.id
group by venue_id
)
) p
group by venue_id;
可以通过减去总和轻松地计算出差异。
答案 1 :(得分:0)
您可以将两个表合并在一起。
SELECT c.venue_id, c.user_id
SUM(c.points) AS total_points,
IFNULL(r.points_redeemed, 0) AS points_redeemed,
SUM(c.points) - IFNULL(r.points_redeemed, 0) AS points_remaining
FROM check_ins AS c
LEFT JOIN (
select venue_id, user_id, sum(points) as points_redeemed
from reward_redemptions
JOIN rewards on reward_redemptions.reward_id = rewards.id
GROUP BY venue_id, user_id) AS r
ON c.venue_id = r.venue_id AND c.user_id = r.user_id
GROUP BY c.venue_id, c.user_id
必须使用左联接才能包含尚未兑换任何内容的用户。