这篇文章的更通用的标题是
MySql根据另一行的值,按另一行的值
对同一表中的不同列求和
我有一份员工开支表:
id | employee_id | expense_cat_id | expense_amount |
1 | 11 | 1 | 100 |
2 | 11 | 1 | 200 |
3 | 12 | 1 | 120 |
4 | 12 | 1 | 140 |
5 | 11 | 2 | 5 |
6 | 12 | 2 | 8 |`
我希望制作一份这样的报告:
Employee Id | Expense Cat 1 Total Amount | Expense Cat 2 Total Amount
11 | 300 | 5
12 | 260 | 8
所以最初我认为我可以在同一个表中使用2个表别名:
SELECT
employee_id,
sum(expense_cat_1.expense_amount) as expense_1_total,
sum(expense_cat_2.expense_amount) as expense_2_total
FROM
expenses as expense_cat_1 where expense_cat_1.expense_cat_id=1 ,
expenses as expense_cat_2 where expense_cat_2.expense_cat_id=2
group by employee_id
但这不是正确的Sql语法,这对我来说很有意义。
所以我认为我可以在employee表和费用表之间进行两次连接:
SELECT
employees.id as employee_id,
sum(expenses_cat_1.expense_amount) as expense_1_total,
sum(expenses_cat_2.expense_amount) as expense_2_total
FROM employees
join expenses as expenses_cat_1 on employees.id = expenses_cat_1.employee_id and expenses_cat_1.expense_cat_id=1
join expenses as expenses_cat_2 on employees.id = expenses_cat_2.employee_id and expenses_cat_2.expense_cat_id=2
group by employees.id
哪个接近,但是错了:
employee_id | expense_1_total | expense_2_total
11 | 300 | 10
12 | 260 | 16
因为费用2总计加倍!我认为这是因为连接为类别1的两个费用中的每一个显示两行,并将它们相加。
我还尝试了一种子查询方法:
SELECT (SELECT sum(expense_amount)
FROM expenses
WHERE expense_cat_id = 1) AS sum1 ,
(SELECT sum(expense_amount)
FROM expenses
WHERE expense_cat_id = 2) AS sum2,
employee_id
FROM expenses group by employee_id
但这与连接方法有同样的问题 - cat 2的总数加倍。
如何使第二次加入仅包括expense_2_total一次???
我个人不喜欢sql case语句,因为它们看起来更像是一个过程语言结构(并且sql是声明性的),但很高兴考虑在这种情况下使用它们 - 但我把挑战放在那里为sql专家优雅地解决这个问题。
答案 0 :(得分:0)
您正在寻找条件聚合:
SELECT employee_id,
sum(case when expense_cat_id = 1 then expense_amount else 0 end) as expense_1_total,
sum(case when expense_cat_id = 2 then expense_amount else 0 end) as expense_2_total
FROM expenses e
GROUP BY employee_id;