我有两个表(时间表和任务),每个表包含一个小时值列“已分配小时数”和“实际小时数”,我试图获得这两个值的总和。 时间表表格包含“staff_id”的整数值,对应于任务表中的“assigned_to”
任务表包含:
task_id INT(11)
assigned_to INT(11)
date_start DATE
hrs DECIMAL (10,0)
时间表表包含:
timesheet_id (int)
name varchar(100)
hours decimal(10,0)
staff_id(INT 11)
我的查询如下:
SELECT
timesheet.staff_id,
task.assigned_to,
SUM(task.hrs) AS assigned_hrs,
timesheet.name,
SUM(timesheet.hours) AS actual_hours
FROM timesheet
INNER JOIN task
ON timesheet.staff_id = task.assigned_to
GROUP BY timesheet.name
将(错误地)导致:
staff_id |assigned_to |assigned_hrs | name. | actual_hours |
---------------|------------|----------------|---------------|---------------|
4 |4 | 1364 | John Smith |52
2 |2 | 80 | Jane Doe |14.5
6 |6 | 454 | Test User 1 |40
9 |9 | 262 | Test User 2 |4
以上是我想要的,但是 所有的结果都是正确的,但约翰史密斯的分配时间增加了一倍。 我知道这与“分组陷阱”有关 如下所述:
http://wikido.isoftdata.com/index.php/The_GROUPing_pitfall
但我只是试图弄明白这一点。 有人能指出我正确的方向吗?
(再次编辑) 如果我只在任务表上运行查询:
SELECT
task.assigned_to,
SUM(task.hrs) AS allocated_hrs
FROM task
GROUP BY task.assigned_to
它(正确)导致:
assigned_to | allocated_hrs |
----------------------------
4 | 682
7 | 378
2 | 40
6 | 227
9 | 262
你可以看到约翰史密斯的用户ID“4”翻了一倍(也是ID 6)
仅在时间表表格上运行查询:
SELECT
timesheet.name,
SUM(timesheet.hours) AS actual_hours
FROM timesheet
GROUP BY timesheet.name
正确导致:
name | Actual_hrs
-------------------------
Jane Doe | 19.5
John Smith | 6.5
Test User1 | 4
Test User2 | 5
运行JoachimL提供的查询导致:
staff_id | assigned_to | assigned_hrs | name | actual_hours
----------------------------------------------------------------------
2 2 40 Jane Doe 19.5
4 4 24 John Smith 6.5
4 4 7 John Smith 6.5
4 4 21 John Smith 6.5
4 4 210 John Smith 6.5
4 4 28 John Smith 6.5
4 4 91 John Smith 6.5
6 6 14 Test User 1 8
6 6 91 Test User 1 8
6 6 28 Test User 1 8
6 6 3 Test User 1 8
9 9 24 Test User 2 1
9 9 91 Test User 2 1
9 9 56 Test User 2 1
答案 0 :(得分:0)
没有评论私人......
ID 4和6在时间表中有两行吗?其他人只有一个?然后task.hrs会加倍。
这样的事情应该避免这种情况。 如果task_id是唯一的,则不必总结。 (测试数据会有所帮助)
修改
SELECT
ts.staff_id,
task.assigned_to,
task.hrs AS assigned_hrs,
ts.name,
ts.actual_hours
FROM task
INNER JOIN (SELECT staff_id, name, SUM(hours) as actual_hours FROM timesheet GROUP BY staff_id, name) as ts
ON ts.staff_id = task.assigned_to
上述:按工作人员/名称分组的工作表时间表 然后加入任务,每个任务应该只有一行
答案 1 :(得分:0)
SELECT
timesheet.staff_id,
task.assigned_to,
SUM(task.hrs) AS assigned_hrs,
timesheet.name,
SUM(timesheet.hours) AS actual_hours
FROM task
LEFT JOIN timesheet ON timesheet.staff_id = task.assigned_to
GROUP BY timesheet.staff_id
尝试LEFT JOIN并确保按UNIQUE字段分组。 “名称”可能不是唯一的。
注意:LEFT JOIN将遗漏未分配给任务的任何时间表。您可以通过SELECT FROM timesheet LEFT JOIN任务来反转它。
修改:请参阅以下答案:Select multiple sums with MySQL query and display them in separate columns
抱歉,还没有评论权限。
答案 2 :(得分:0)
SELECT x.*
, SUM(y.hrs) n
FROM
( SELECT t.staff_id
, t.name
, SUM(t.hours) actual_hours
FROM timesheet t
GROUP
BY t.staff_id
) x
JOIN task y
ON y.assigned_to = x.staff_id
GROUP
BY staff_id;