我需要根据参加的会议,扣除和奖金来计算员工的月薪; 根据工作岗位,员工每次会议的薪酬不同。
解决方案是: salary =(Pay_per_minute * meetings_attended)+奖金 - 扣除;
我有四张桌子:
工作: ID,title,pay_per_meeting
员工: Id,Name,job_id
奖金: ID,金额,employee_id,日期
扣减: ID,金额,employee_id,日期
会议: ID,employee_id,日期
SELECT
COUNT(meetings.employee_id) as meetings_attended,
COUNT(deductions.amount) as debt,
COUNT(bonuses.amount) bonus,
(SELECT jobs.pay_per_attendance from jobs where jobs.id = (select job_id from employees where id=meetings.employee_id)) as pay,
((meetings_attended * pay) + bonus - debt) as salary
FROM meetings
JOIN deductions ON deductions.employee_id = meetings.employee_id
JOIN bonuses ON bonuses.employee_id = meetings.employee_id
WHERE meetings.employee_id = 1
GROUP BY MONTH(meetings.date), MONTH(deductions.date), MONTH(bonuses.date)
每当我删除工资行时,上面的查询都会返回许多不正确的值,但会出现未知列薪,meeting_attended,债务和奖金的错误,我确定分组有问题,但我不能只看到它。
答案 0 :(得分:1)
您无法在定义的同一选择列表中引用列别名,您需要引用基础列。子查询无法访问主查询中计算的聚合。您需要重复聚合表达式,或将所有内容移动到子查询中,并在外部查询中使用它进行计算。
此外,所有COUNT()
表达式都将返回相同的内容,因为它们只是计算行数(我假设这些值都不是NULL
)。您可能希望COUNT(DISTINCT <column>)
获得不同的计数,并且您需要使用唯一的列,因此它们应该是主键列,例如COUNT(DISTINCT deductions.id)
。
另一个问题是,当您尝试在多个连接时对值进行求和并计算时,最终得到的结果太高,因为行在所有表的叉积中都会重复。见Join tables with SUM issue in MYSQL。解决方案是计算子查询中每个表的总和。
SELECT m.month, m.meetings_attended, d.debt, b.bonus,
m.meetings_attended * j.pay_per_meeting + b.amount - d.amount AS salary
FROM (
SELECT MONTH(date) AS month, COUNT(*) AS meetings_attended
FROM meetings
WHERE employee_id = 1
GROUP BY month) AS m
JOIN (
SELECT MONTH(date) AS month, COUNT(*) AS bonus, SUM(amount) AS amount
FROM bonuses
WHERE employee_id = 1
GROUP BY month) AS b ON m.month = b.month
JOIN (
SELECT MONTH(date) AS month, COUNT(*) AS debt, SUM(amount) AS amount
FROM deductions
WHERE employee_id = 1
GROUP BY month) AS d ON m.month = d.month
CROSS JOIN employees AS e
JOIN jobs AS j ON j.id = e.job_id
WHERE e.employee_id = 1