【问题标题】:Mysql Why when I use group by Id the sum function doesn't calculate the summation of a columnMysql 为什么当我使用 group by Id 时 sum 函数不计算列的总和
【发布时间】:2020-12-13 11:34:51
【问题描述】:

我们公司有员工,员工从他们的工资中借了一些钱,这些借来的钱是要让我们知道的。我们还需要知道每笔交易的工资中剩余的钱,以及借来的钱。

我创建了包括薪水列的员工表

作为

CREATE TABLE `employees` (
 `Employee_Id` int(11) NOT NULL AUTO_INCREMENT,
 `Employee_Name` varchar(100) NOT NULL,
 `Salary` decimal(10,0) NOT NULL,
 PRIMARY KEY (`Employee_Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2

和salary_transaction表把每笔借来的钱存到money_amount列

CREATE TABLE salary_transaction (
 Salary_Transaction_Id int(11) NOT NULL AUTO_INCREMENT,
 Employee_Id int(11) NOT NULL,
 money_amount decimal(10,0) NOT NULL,
 PRIMARY KEY (Salary_Transaction_Id)
 
) ENGINE=InnoDB AUTO_INCREMENT=3  

这是我的查询,问题是它没有计算特定员工借用的 money_amount 的累计总和。

SELECT t.Salary_Transaction_Id,
t.Employee_Id,t.money_amount,
sum(t.money_amount) as Total_borrowed,
e.salary-sum(t.money_amount) as remaining from salary_transaction t
JOIN
(SELECT salary,Employee_Id,Employee_Name from employees ) e 
ON
t.Employee_Id = e.Employee_Id GROUP by t.salary_transaction_id 

编辑

我用脚本提供了我的问题

All scripts here

编辑 2

预期的总借用值

【问题讨论】:

标签: mysql mariadb


【解决方案1】:
select t.salary_transaction_id, 
       t.employee_id, 
       t.money_amount, 
       sum(t.money_amount) over (partition by employee_id order by t.salary_transaction_id) as total_borrowed, 
       e.salary - sum(t.money_amount) over (partition by e.employee_id order by t.salary_transaction_id) remaining
from employees e
inner join salary_transaction t on t.employee_id = e.employee_id
group by t.employee_id, t.salary_transaction_id, t.money_amount

你可以使用OVER()函数。

salary_transaction_id | employee_id | money_amount | total_borrowed | remaining
         1            |       1     |     3000     |       3000     |    4000
         2            |       1     |     1000     |       4000     |    3000
         3            |       1     |      500     |       4500     |    2500

【讨论】:

    【解决方案2】:

    您想从每个员工的工资中减去他们借入的总金额。我会推荐一个带有预聚合的left join

    select e.*,
        coalesce(st.total_borrowed, 0) as total_borrowed,
        e.salary - coalesce(st.total_borrowed, 0) as remaining
    from employee e
    left join (
        select employee_id, sum(money_amount) as total_borrowed
        from salary_transaction
        group by employee_id
    ) st on st.employee_id = e.employee_id
    

    您也可以使用相关子查询。在最新版本的 MySQL 中,横向连接很方便:

    select e.*, st.total_borrowed, e.salary - st.total_borrowed as remaining
    from employee e
    cross join lateral (
        select coalesce(sum(money_amount), 0) as total_borrowed
        from salary_transaction st
        where st.employee_id = e.employee_id
    ) st
    

    编辑:这两个查询都为每个员工提供一行。如果你真的想要每笔交易一行,借来的钱和剩余的工资,那就不同了。

    在 MySQL 8.0 中,您可以使用窗口函数:

    select e.*,
        st.salary_transaction_id, st.money_amount,
        coalesce(sum(st.money_amount) over(partition by employee_id order by st.salary_transaction_id), 0) as total_borrowed,
        e.salary - coalesce(sum(st.money_amount) over(partition by employee_id order by st.salary_transaction_id), 0) as remaining
    from employee e
    left join salary_transaction st using(employee_id)
    

    在早期版本中,另一种选择是相关子查询:

    select t.*, salary - total_borrowed
    from (
        select e.*,
            st.salary_transaction_id, st.money_amount,
            (
                select coalesce(sum(st.money_amount), 0) 
                from salary_transaction st1
                where st.employee_id = e.employee_id and st1.salary_transaction_id <= st.salary_transaction_id
            ) as total_borrowed
        from employee e
        left join salary_transaction using(employee_id)
    ) t
    

    【讨论】:

    • 您的第一个查询没有显示所有交易
    • 第二个查询SQL语法错误。
    • @Nefazodone:所以你想要每笔交易一行而不是每名员工一行?看我的更新。请注意,解决方案取决于您的 MySQL 版本(在第二个查询中已明确提及),因此请确保使用适合您的数据库版本的解决方案。
    • 每笔交易我都想要一行,我的maiadb不是最近的
    • 请看我的编辑2
    猜你喜欢
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2013-02-04
    • 2022-01-05
    相关资源
    最近更新 更多