加入三个表,包括总和和计数

时间:2017-04-12 10:25:18

标签: mysql

我有三张桌子

[用户]

id
name
email

[交易]

id
user_id
amount
points_rewarded

[赎回]

id
user_id
points_redeemed

我想查询数据库以获取以下字段

users.id
users.name
transactions   //   Number of transactions
redemptions    //   Number of redemptions
points         //   Sum of points_rewarded - sum of points_redeemed

我可以设法将用户表加入交易或兑换,但我似乎无法在一个查询中加入所有三个。

[使用者+交易]

SELECT users.id,users.name,COUNT(transactions.id) AS transactions,SUM(transactions.points_rewarded) AS points_rewarded FROM users LEFT JOIN transactions ON users.id=transactions.user_id GROUP BY users.id, users.name

其中为users.id,users.name,transactions和points_rewarded提供了正确的值。

[使用者+赎回]

SELECT users.id,users.name,COUNT(redemptions.id) AS redemptions, IFNULL(SUM(redemptions.points_redeemed),0) AS points_redeemed FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id GROUP BY users.id, users.name

这为users.id,users.name,redemptions和points_redeemed提供了正确的值。

如果我只是使用

离开加入
SELECT users.id,users.name,COUNT(transactions.id) AS transactions,COUNT(redemptions.id) AS redemptions,SUM(transactions.points_rewarded) - IFNULL(SUM(redemptions.points_redeemed),0) AS points FROM users LEFT JOIN transactions ON users.id=transactions.user_id LEFT JOIN redemptions on users.id=redemptions.user_id GROUP BY users.id, users.name

我获得了兑换列的错误值。我基本上得到所有points_rewarded值乘以赎回的总数,使得积分(points_rewarded - points_redeemed)为负值,这是不可能的。

任何帮助都会很棒!

2 个答案:

答案 0 :(得分:0)

是的,因为左连接将返回一个记录联合,这可能会改变应该并且将独立应用于每个集合的总和(就像使用2个单独的查询时一样)

所以是的,两个查询仍然必须在“主”查询中共存:

SELECT users.id, 
       users.name, 
       t.transactions, 
       r.redemptions, 
       t.points_rewarded - r.points_redeemed AS points 
FROM   users 
       LEFT JOIN (
        SELECT 
            users.id, 
            COUNT(*) AS transactions,
            COALESCE(SUM(transactions.points_rewarded),0) AS points_rewarded 
        FROM users LEFT JOIN transactions ON users.id=transactions.user_id 
        GROUP BY users.id
       ) t ON users.id = t.user_id 
       LEFT JOIN (
        SELECT 
            users.id,
            COUNT(*) AS redemptions, 
            COALESCE(SUM(redemptions.points_redeemed),0) AS points_redeemed 
        FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id 
        GROUP BY users.id
       ) r ON users.id = r.user_id
;

答案 1 :(得分:0)

根据Sebas的回答,我最后的查询是:

SELECT 
  users.id, 
  users.name, 
  COALESCE(t.transactions,0) AS transactions, 
  COALESCE(t.points_rewarded,0) AS points_rewarded, 
  COALESCE(r.redemptions,0) AS redemptions, 
  COALESCE(r.points_redeemed,0) AS points_redeemed,
  COALESCE(t.points_rewarded,0)-COALESCE(r.points_redeemed,0) AS points 
  FROM users 
  LEFT JOIN (
       SELECT 
       users.id, 
       transactions.user_id, 
       COALESCE(COUNT(transactions.id),0) AS transactions, 
       COALESCE(SUM(transactions.points_rewarded),0) AS points_rewarded 
       FROM users 
       LEFT JOIN transactions ON users.id=transactions.user_id 
       GROUP BY users.id) t 
  ON users.id=t.user_id 
  LEFT JOIN (
       SELECT 
       users.id,
       redemptions.user_id,
       COALESCE(COUNT(redemptions.id),0) AS redemptions,
       COALESCE(SUM(redemptions.points_redeemed),0) AS points_redeemed
       FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id
       GROUP BY users.id) r 
  ON users.id=r.user_id

现在剩下的就是把它变成更“滔滔不绝”的东西; - )

相关问题