从sql(mysql)中的两个不同表中减去计算值

dced5bon  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(431)

在我的程序中,用户可以通过在某个地点执行签入来赚取积分。
然后,他们可以使用这些积分在该地点兑换奖励。积分不可跨场馆共享。
我有以下表格:
用户
身份证件
名称
场馆
身份证件
名称
签入
身份证件
user\u id(fk):获得积分的用户
场馆标识(fk):用户在其中获得积分的场馆
点数:获得的点数
奖励
身份证件
名称
地点\u id:奖励所属的地点
积分:奖励成本的金额
奖励和赎回
身份证件
用户id
奖励id
我可以按地点计算用户的总分,如下所示:

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来实现这一点(最好是在一个查询中,以减少在查询之间更改数据的机会,使代码更简单,并可能提高性能)。理想的最终结果是:

venue_id    total_points    points_redeemed     points_remaining      

# 5          10              2                   8

# 15         25              10                  15

# 189        150             20                  130

所以我的问题是:
是否可以在一次查询中获得全部积分和兑换的积分?
是否可以在一次查询中获得总积分、兑换积分和剩余积分?

zbdgwd5y

zbdgwd5y1#

你可以用 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;

通过减去总和,可以很容易地计算出差值。

8ulbf1ek

8ulbf1ek2#

您可以将这两个表合并起来。

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

左联接对于包含尚未兑换任何东西的用户是必需的。

相关问题