【问题标题】:mysql join 1 table to 2 other tablesmysql将1个表连接到其他2个表
【发布时间】:2019-02-22 20:41:09
【问题描述】:

我需要将项目中每个任务的实际小时数与估计小时数进行比较。信息存在于 3 个不同的表中

任务表:包含所有项目任务信息

  • 任务 ID(键)
  • 任务名称
  • 项目名称

时间表表:包含记录到任务的实际小时数

  • 任务 ID
  • 任务名称
  • 小时数(总和)[每个任务的多个时间表记录]

任务所有者表:包含分配给任务的估计小时数

  • 任务 ID
  • 任务名称
  • 预计小时数(总和)[每个任务的多个任务所有者记录]

我需要从 Tasks 表中提取任务信息、从时间表表中提取实际小时数的总和以及从 Task Owner 表中提取估计小时数的总和

它应该是这样的:

Project Name | Task Name | Actual Hours | Estimated Hours

这是我的起始查询,它显示了每个项目任务的实际总小时数。现在我需要知道如何为总估计小时数添加一列

SELECT
tasks."Project Name" AS "Project Name",
tasks."Task Name" AS "Task Name",
sum("Timesheets"."Hours") AS "Hours"
FROM "Tasks" join "Timesheets" ON "Tasks"."Task ID" = "Timesheets"."Task ID"
GROUP BY tasks."Project Name", tasks."Task Name"

【问题讨论】:

标签: mysql


【解决方案1】:

可以将聚合列分配给select 子查询:

SELECT
tasks."Project Name" AS "Project Name",
tasks."Task Name" AS "Task Name",
(select sum("Timesheets"."Hours" FROM "Timesheets" where "Timesheets"."Task ID" = "Tasks"."Task ID") as "Hours",
(select sum("Task Owner"."Hours" FROM "Timesheets" where "Task Owner"."Task ID" = "Tasks"."Task ID") as "Estimated Hours"
FROM "Tasks"

【讨论】:

  • 您忘记了 sum(... 的右括号。你在第二个子查询中混淆了列名和表名。
【解决方案2】:

在此处预先汇总您在子查询中的实际和估计小时数然后将其加入可能会有所帮助。如果您的 Task OwnerTimesheets 表对于每个不同的 @987654323 都有很多行,这一点尤其重要@。

SELECT
    tasks.`Project Name` AS `Project Name`,
    tasks.`Task Name` AS `Task Name`,
    actual.hours,
    estimated.hours,
FROM Tasks 
    INNER JOIN (SELECT `TASK ID`, SUM(Hours) as hours FROM Timesheets GROUP BY `TASK ID`) actual
        ON Tasks.`Task ID` = actual.`Task ID`
    INNER JOIN (SELECT `TASK ID`, SUM(`Estimated Hour`) as hours FROM `Task Owner` GROUP BY `TASK ID`) estimated 
        ON Tasks.`TASK ID` = estimated.`TASK ID`

使用此方法可确保每个子查询返回每个 task id 的唯一记录以及估计或实际小时数的总和。

【讨论】:

    【解决方案3】:

    您不能直接将三个表连接在一起,因为“时间表”和“任务所有者”在“任务 ID”列中可能有重复的值。为避免在加入时生成更多行,您需要事先对这些表进行分组。这可以通过子查询来完成,但使用 WITH 会产生干净的代码。

    WITH actual AS (
        SELECT
            "Task ID",
            SUM(Hours) AS hours
        FROM "Task Owner"
        GROUP BY "Task ID"
    ),
    
    estimated AS (
        SELECT
            "Task ID",
            SUM(Hours) AS hours
        FROM Timesheets
        GROUP BY "Task ID"
    )
    
    SELECT 
        t."project name"      AS "Project Name", 
        t."task name"         AS "Task Name", 
        a.hours               AS "Actual Hours"
        e.hours               AS "Estimated Hours"
    FROM tasks t
    LEFT JOIN actual a
        ON t."task id" = a."task id" 
    LEFT JOIN estimated e
        ON t."task id" = e."task id" 
    GROUP  BY tasks."project name", 
        tasks."task name" 
    

    【讨论】:

      【解决方案4】:

      您应该添加另一个联接:

      SELECT
          tasks.`Project Name` AS `Project Name`,
          tasks.`Task Name` AS `Task Name`,
          sum(`Timesheets`.`Hours`) AS `Hours`
          sum(`Task Owner`.Estimated Hour`) AS `Estimated Hour`
          FROM `Tasks` 
          join `Timesheets` ON `Tasks`.`Task ID` = `Timesheets`.`Task ID`
          join `Task Owner`  ON `Tasks`.`Task ID` = `Task Owner`.`Task ID`
      
      GROUP BY tasks.`Project Name`, tasks.`Task Name`
      

      我想建议您使用反引号而不是双引号来表示表名和列名。

      【讨论】:

      • 当给定任务 ID 的两个子表中都有多行时,此查询模式将给出半笛卡尔积......例如来自 Timesheets 的两行和来自 Task Owner 的三行,将生成六行...... SUM() 聚合将是预期值的两倍或三倍。
      猜你喜欢
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 2011-08-18
      • 2015-07-22
      • 1970-01-01
      • 2016-02-17
      相关资源
      最近更新 更多