为什么在使用左联接时sum不能在MYSQL中工作?

问题描述

**Here is my sample data:**

Users table:

    +------------+--------------+-------------+
    | user_id    | user_name    | credit      |
    +------------+--------------+-------------+
    | 1          | Moustafa     | 100         |
    | 2          | Jonathan     | 200         |
    | 3          | Winston      | 10000       |
    | 4          | Luis         | 800         | 
    +------------+--------------+-------------+

Transaction table:
+------------+------------+------------+----------+---------------+
| trans_id   | paid_by    | paid_to    | amount   | transacted_on |
+------------+------------+------------+----------+---------------+
| 1          | 1          | 3          | 400      | 2020-08-01    |
| 2          | 3          | 2          | 500      | 2020-08-02    |
| 3          | 2          | 1          | 200      | 2020-08-03    |
+------------+------------+------------+----------+---------------+

我必须在每个客户帐户中找到净额,并告诉交易后净额是否小于0

结果表:

+------------+------------+------------+-----------------------+
| user_id    | user_name  | credit     | credit_limit_breached |
+------------+------------+------------+-----------------------+
| 1          | Moustafa   | -100       | Yes                   | 
| 2          | Jonathan   | 500        | No                    |
| 3          | Winston    | 9900       | No                    |
| 4          | Luis       | 800        | No                    |

我正在尝试以下代码

select user_id,user_name,sum(users.credit + k.credit) credit,case
when ifnull((users.credit + k.credit),users.credit) < 0 then "Yes"
else "No"
end as credit_limit_breached
from users
left join (select id,sum(credit)credit 
from (select paid_by as id,sum(-amount)credit from transaction group by id
union
select paid_to as id,sum(amount)credit from transaction group by id) tem
group by id) k
on k.id = users.user_id

它为Luis(他没有做任何交易)提供空值,所以出了什么问题。

解决方法

取消透视交易,然后加入并汇总:

select user_id,sum(credit) as credit,sum(debit) as debit
from ((select paid_to as user_id,sum(amount) as credit,0 as debit
       from transactions t
       group by paid_to
      ) union all
      (select paid_from as user_id,sum(amount)
       from transactions t
       group by paid_from
      )
     ) t
group by user_id;

然后加入以获得最终结果:

select u.*,u.credit + t.credit - u.debit,(case when u.credit + t.credit - u.debit < 0 then 'yes' else no' end)
from users u left join
     (select user_id,sum(debit) as debit
      from ((select paid_to as user_id,0 as debit
             from transactions t
             group by paid_to
            ) union all
            (select paid_from as user_id,sum(amount)
             from transactions t
             group by paid_from
            )
           ) t
      group by user_id
     ) t
     on t.user_id = u.user_id
,

您当前的查询非常接近。您可以使用coalesce()为完全没有交易的用户分配默认值0。另外,您也不需要(也不需要)外部查询中的sum():简单的添加就足够了。

所以:

select 
    u.user_id,u.user_name,u.credit + coalesce(k.credit,0) credit,case when u.credit < coalesce(k.credit,0) then 'Yes' else 'No' end as credit_limit_breached
from users u
left join (
    select id,sum(credit) credit 
    from (
        select paid_by as id,sum(-amount) credit from transaction group by id
        union all
        select paid_to as id,sum(amount) credit from transaction group by id
    ) t
    group by id
) k on k.id = users.user_id

另一种方法是相关子查询:

select 
    x.*,case when credit < 0 then 'Yes' else 'No' end as credit_limit_breached
from (
    select
        u.user_id,u.credit + (
            select coalesce(sum(case when u.user_id = t.paid_for then amount else - amount end),0)
            from transaction t
            where u.user_id in (t.paid_by,t.paid_for)
        ) as as credit
    from users u
) x

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...