如何在单独的表上的多个列上滚动SUM?

时间:2017-06-12 19:37:43

标签: mysql

我有4个表,我希望使用MySQL 5.7汇总数据。

Projects
+------------+--------+------------------+
| project_id | org_id |       name       |
+------------+--------+------------------+
|          1 |      1 | Big Project      |
|          2 |      1 | Internal Project |
+------------+--------+------------------+

Tasks
+-----------+--------+----------------+------------+
|  task_id  | org_id |      name      | project_id |
+-----------+--------+----------------+------------+
|         1 |      1 | Check Work     |          1 |
|         2 |      1 | Fix Code       |          1 |
|         3 |      1 | Rebuild Office |          2 |
+-----------+--------+----------------+------------+

Resources
+-------------+--------+-------------+-----------+
| resource_id | org_id |  first_name | last_name |
+-------------+--------+-------------+-----------+
|           1 |      1 | Alice       | Black     |
|           2 |      1 | Bob         | Smith     |
|           3 |      1 | Charlie     | White     |
+-------------+--------+-------------+-----------+

Task_Details
+-------------+--------+---------+-------------+
| resource_id | org_id | task_id | total_hours |
+-------------+--------+---------+-------------+
|           1 |      1 |       1 |          12 |
|           2 |      1 |       1 |           4 |
|           3 |      1 |       1 |           8 |
|           2 |      1 |       2 |           4 |
|           3 |      1 |       2 |           4 |
|           1 |      1 |       3 |          16 |
+-------------+--------+---------+-------------+

我希望将total_hours,GROUPing by task和project相加,同时仍然显示每个员工单独花在任务上的total_hours。我正在寻找的输出将是这样的

Desired Output
+------------------+----------------+------------+-----------+-------------+
|   project_name   |   task_name    | first_name | last_name | total_hours |
+------------------+----------------+------------+-----------+-------------+
| Big Project      | Check Work     | Alice      | Green     |          12 |
| Big Project      | Check Work     | Bob        | Smith     |           4 |
| Big Project      | Check Work     | Charlie    | Brown     |           8 |
| Big Project      | Check Work     | NULL       | NULL      |          24 |
| Big Project      | Fix Code       | Bob        | Smith     |           4 |
| Big Project      | Fix Code       | Charlie    | Brown     |           4 |
| Big Project      | Fix Code       | NULL       | NULL      |           8 |
| Big Project      | NULL           | NULL       | NULL      |          32 |
| Internal Project | Rebuild Office | Alice      | Green     |          16 |
| Internal Project | Rebuild Office | NULL       | NULL      |          16 |
| Internal Project | NULL           | NULL       | NULL      |          16 |
+------------------+----------------+------------+-----------+-------------+

我设法创建了一个将相关表连接在一起的查询,甚至设法通过project_id,task_id和resource_id对它们进行GROUP。但是,在我的查询结尾添加WITH ROLLUP语句会导致它失败,即使它没有一个也可以。

这是我目前的查询:

SELECT
    t1.project_name,
    t1.task_name,
    t2.first_name,
    t2.last_name,
    SUM(t1.task_hours)
FROM (
   SELECT
        Projects.project_id,
        Projects.name AS project_name,
        Tasks.task_id,
        Tasks.name AS task_name,
        Resources.resource_id,
        Task_Details.total_hours AS task_hours
    FROM
        Projects
    RIGHT OUTER JOIN
        Tasks
    ON
        Projects.org_id = Tasks.org_id AND
        Projects.project_id = Tasks.project_id
    LEFT OUTER JOIN
        Task_Details
    ON
        Task_Details.org_id = Tasks.org_id AND
        Task_Details.task_id = Tasks.task_id
    LEFT OUTER JOIN
        Resources
    ON
        Resources.org_id = Task_Details.org_id AND
        Resources.resource_id = Task_Details.resource_id
    WHERE
        Projects.org_id = 1 
) AS t1
JOIN (
    SELECT
        resource_id,
        first_name,
        last_name
    FROM
        Resources
    WHERE
        org_id = 1
) AS t2
ON
    t2.resource_id = t1.resource_id
GROUP BY
    t1.project_id,
    t1.task_id,
    t1.resource_id;

如何修改我的查询以使WITH ROLLUP有效?

我的SQLFiddle是here,但值得注意的是MySQL 5.6而不是5.7

1 个答案:

答案 0 :(得分:0)

恕我直言,您的查询存在的问题是:您选择了一些不在GROUP BY中的列。这会在first_namelast_nameproject_nametask_name列中产生一些非感性值。但是,sum列可能是正确的,不是吗?

这对我有用:

SELECT p.name as project_name, 
    s1.task_name, 
    first_name,
    last_name, 
    s1.total_hours 
    FROM (
         SELECT 
         t.project_id, 
         t.name as task_name, 
         h.resource_id, 
         sum(h.total_hours) as total_hours 
         FROM Task_Details as h 
         JOIN Tasks as t ON (t.task_id=h.task_id) 
         GROUP BY t.project_id, t.name, h.resource_id WITH ROLLUP
      ) AS s1 
      LEFT JOIN Resources AS r ON (s1.resource_id=r.resource_id) 
      JOIN Projects AS p ON (p.project_id=s1.project_id);

嵌套SELECT执行有趣的工作,它总结了每resource_id,每task_name和每project_id的total_hours。然后,嵌套SELECT将收集每个资源和项目的名称。

输出:

+------------------+----------------+------------+-----------+-------------+
| project_name     | task_name      | first_name | last_name | total_hours |
+------------------+----------------+------------+-----------+-------------+
| Big Project      | NULL           | NULL       | NULL      |          32 |
| Big Project      | Check Work     | Alice      | Green     |          12 |
| Big Project      | Check Work     | NULL       | NULL      |          24 |
| Big Project      | Check Work     | Bob        | Smith     |           4 |
| Big Project      | Check Work     | Charlie    | Brown     |           8 |
| Big Project      | Fix Code       | Bob        | Smith     |           4 |
| Big Project      | Fix Code       | Charlie    | Brown     |           4 |
| Big Project      | Fix Code       | NULL       | NULL      |           8 |
| Internal Project | NULL           | NULL       | NULL      |          16 |
| Internal Project | Rebuild Office | NULL       | NULL      |          16 |
| Internal Project | Rebuild Office | Alice      | Green     |          16 |
+------------------+----------------+------------+-----------+-------------+

希望这有帮助。