2014-04-25 75 views
4

我有兩個表(時間表和任務)每個包含一個小時值列「分配小時數」和「實際小時數」,其中我試圖得到這兩個值的總和。 也時間表表包含「staff_id」一個整數值,其對應於在任務表中的「assigned_to」mysql group通過返回不正確的結果

任務表包含:

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 

這裏有一個小提琴http://sqlfiddle.com/#!2/ef680

+0

請編輯您的查詢,包括產生不正確的結果的數據。 –

+0

你怎麼樣GROUP BY timesheet.staff_id?也許有兩個約翰史密斯的? –

+1

考慮提供適當的DDL(和/或sqlfiddle)與期望的結果集 – Strawberry

回答

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; 

http://sqlfiddle.com/#!2/ef680/14

+0

太棒了! 非常感謝! 我一直在爲此奮鬥了幾天,現在我將分析你最聰明的問題,並從主人那裏學習:) 有一個美好的週末 歡呼聲 馬丁 – Lookfar

+0

謝謝*所有*的建議和解決方案,它是不勝感激。這是我第一次使用這個網站,我對這裏的廣博知識印象深刻! – Lookfar

0

無可奉告PRIVS ...

時間表中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 

以上:通過staff_id /名組時間表 然後用任務加入,這應該是每個任務

+0

是時間表表格將保存將輸入每天的實際時間的同一用戶的多個條目。 – Lookfar

+0

桌子的設計似乎令人懷疑。用戶不能完成兩項任務嗎?如果是這種情況,時間表中的條目將計入兩項任務。我認爲至少需要加入兩個領域。 – Joachim

+0

是的,用戶可能有許多小時分配給他作爲不同的任務。 然後他將輸入他的每個任務的實際時間。 這就是爲什麼我需要比較這兩個 – Lookfar

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時間表LEFT JOIN任務來改變它。

編輯:看到這個答案:尚未Select multiple sums with MySQL query and display them in separate columns

對不起,無可奉告特權。

+0

這導致與第一個結果相同,它將allocated_hrs加倍。 – Lookfar