mysql连接3个表与group by group by

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql连接3个表与group by group by相关的知识,希望对你有一定的参考价值。

我有三张桌子

users:

+----+--------+--------------+
| id | name   | user_type_id |
+----+--------+--------------+
|  1 | Tawsif |            1 |
|  2 | Karim  |            2 |
+----+--------+--------------+
transactions:
+----+---------+--------+
| id | user_id | amount |
+----+---------+--------+
|  1 |       1 |     10 |
|  2 |       2 |     10 |
|  3 |       1 |     10 |
+----+---------+--------+
course_fee:
+----+---------+-----+
| id | user_id | fee |
+----+---------+-----+
|  1 |       1 | 105 |
|  2 |       2 |  33 |
|  3 |       1 | 106 |
+----+---------+-----+

我想从交易和课程费用表中得到total_rows的数量,每个用户交易金额和费用的总和

所以我尝试了这个

SELECT users.id, SUM(transactions.amount) as total_transaction_amount,
count(transactions.id) as transaction_count, 
sum(course_fee.fee) as total_fee, 
count(course_fee.user_id) as total_fee_count 
    FROM users 
INNER join transactions on transactions.user_id = users.id 
INNER join course_fee on course_fee.user_id = users.id 
    GROUP by users.id

结果:

+----+--------------------------+-------------------+-----------+-----------------+
| id | total_transaction_amount | transaction_count | total_fee | total_fee_count |
+----+--------------------------+-------------------+-----------+-----------------+
|  1 |                       40 |                 4 |       422 |               4 |
|  2 |                       10 |                 1 |        33 |               1 |
+----+----------

它返回了错误的结果。我怎样才能解决这个问题?

答案

当您尝试报告来自连接相关的多个表的聚合时,您的问题是一个常见问题。一种理智的方法是加入两个独立的子查询,每个子查询分别汇总交易和费用:

SELECT
    u.id,
    u.name,
    COALESCE(t.amount, 0) AS total_transaction_amount,
    COALESCE(t.cnt, 0)    AS transaction_count,
    COALESCE(c.fee, 0)    AS total_fee,
    COALESCE(c.cnt, 0)    AS total_fee_count
FROM users u
LEFT JOIN
(
    SELECT user_id, COUNT(*) AS cnt, SUM(amount) AS amount
    FROM transactions
    GROUP BY user_id
) t
    ON u.id = t.user_id
LEFT JOIN
(
    SELECT user_id, COUNT(*) AS cnt, SUM(fee) AS fee
    FROM course_fee
    GROUP BY user_id
) c
    ON u.id = c.user_id;

请注意,我们将联接保留在上面,因为用户不会出现在交易表或费用表中。在这种情况下,我们为总和和计数赋值为零。

另一答案

正确的岁月

   SELECT test.id,transaction_count,test.total_transaction_amount, 
    IFNULL(SUM(course_fee.fee),0) AS total_fee, 
    IFNULL(COUNT(course_fee.user_id),0) AS total_fee_count  FROM 
    (
      SELECT users.id, IFNULL(SUM(transactions.amount),0) AS 
      total_transaction_amount,
      IFNULL(COUNT(transactions.id),0) AS transaction_count
      FROM users 
      LEFT JOIN transactions ON transactions.user_id = users.id 
      GROUP BY users.id
    ) AS test 
    LEFT JOIN course_fee ON course_fee.user_id = test.id 
    GROUP BY test.id

这是2nd JOIN之后你的查询中发生的事情,这就是为什么你得到40为id 1的原因

enter image description here

以上是关于mysql连接3个表与group by group by的主要内容,如果未能解决你的问题,请参考以下文章

Mysql UNION 和 GROUP BY

从 3 个表中选择,在两个 group by 之前有两个 order by

sql中 group by排序

将基表值与第二个表的值之和与group by进行比较

MySQL group by 左连接

加入4个表with group by,2 having和where子句