【问题标题】:MySQL JOIN multiple query result to 1 result setMySQL JOIN 多个查询结果到 1 个结果集
【发布时间】:2015-02-07 00:35:50
【问题描述】:

我想在一个键上将多个结果集加入到 1 个结果中。

有3个表(我在这里只添加相关记录):

Project table : | id | project |

File table    : | id | project_id |

Approved table: | file_id | dep1_date | dep2_date | dep3_date |

部门默认为日期字符串:0000-00-00 00:00:00 第一个查询是:

SELECT project.project, 
SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(approved.dep1_date,file.uploaded_datetime)))) as dep1_avg
FROM APPROVED
LEFT JOIN file on file.id = approved.file_id
LEFT JOIN project on project.id=file.project_id
WHERE approved.dep1_date != '0000-00-00 00:00:00'
GROUP BY project.project

它会给我按项目等分组的平均批准时间:

Project    Dep1_avg
project1   01:03:02
project2   04:14:03
project3   00:07:56
...

我也想使用 dep2 和 dep3_date 再运行此查询 2 次,并附加到第一个结果集,但包含不同的 WHERE 状态(approved.dep2_date、approved.dep3_date)。

这样看表怎么办?

Project    Dep1_avg Dep2_avg Dep3_avg
project1   01:03:02          04:23:11
project2   04:14:03 11:33:44
project3   00:07:56 00:13:43 32:24:17
...

另外 2 个结果与第一个查询相同(按项目),如果没有批准等 Dep2 或 Dep3 的一个项目,则它应该为 NULL 或空

查询是什么样的?

谢谢

【问题讨论】:

    标签: mysql sql select if-statement group-by


    【解决方案1】:

    试试这个:

    SELECT project.project, 
           SEC_TO_TIME(AVG(TIME_TO_SEC(IF(approved.dep1_date != '0000-00-00 00:00:00', TIMEDIFF(a.dep1_date, f.uploaded_datetime), NULL)))) AS dep1_avg, 
           SEC_TO_TIME(AVG(TIME_TO_SEC(IF(approved.dep2_date != '0000-00-00 00:00:00', TIMEDIFF(a.dep2_date, f.uploaded_datetime), NULL)))) AS dep2_avg, 
           SEC_TO_TIME(AVG(TIME_TO_SEC(IF(approved.dep3_date != '0000-00-00 00:00:00', TIMEDIFF(a.dep3_date, f.uploaded_datetime), NULL)))) AS dep3_avg
    FROM APPROVED a
    LEFT JOIN `file` f ON f.id = a.file_id
    LEFT JOIN project p ON p.id = f.project_id
    GROUP BY p.project;
    

    【讨论】:

    • 如果你使用数字 0 它仍然会改变平均数字。您应该改用 NULL。
    【解决方案2】:

    您不应使用多个 where 语句来执行此操作,而应选择是否在 select 本身内的 AVG 中包含一行。 (可以通过执行多个子查询来使用多个 where 语句来完成,但这可能效率不高。

    SELECT project.project, 
    SEC_TO_TIME(AVG(IF( approved.dep1_date != '0000-00-00 00:00:00', TIME_TO_SEC(TIMEDIFF(approved.dep1_date,file.uploaded_datetime), NULL))) as dep1_avg
    SEC_TO_TIME(AVG(IF( approved.dep2_date != '0000-00-00 00:00:00', TIME_TO_SEC(TIMEDIFF(approved.dep2_date,file.uploaded_datetime), NULL))) as dep2_avg
    SEC_TO_TIME(AVG(IF( approved.dep3_date != '0000-00-00 00:00:00', TIME_TO_SEC(TIMEDIFF(approved.dep3_date,file.uploaded_datetime), NULL))) as dep3_avg
    FROM APPROVED
    LEFT JOIN file on file.id = approved.file_id
    LEFT JOIN project on project.id=file.project_id
    GROUP BY project.project
    

    NULL 值不包含在 diff 中,所以这基本上只是检查是否不应该包含该值,在这种情况下将其换成 NULL,这将被忽略。这让您可以废弃整个 WHERE 子句。

    【讨论】:

    • 很好的答案,谢谢!,它解决了我的问题。但是,您在上面的代码中有 2 个错误,在 TIME_TO_SEC 语句之后缺少关闭 ),在 SET_TO_TIME 行之后缺少逗号 ,。再次感谢!
    猜你喜欢
    • 2020-03-08
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多