在多个日期列上按年份分组mysql

时间:2019-03-22 09:37:02

标签: mysql sql group-by

我的表格如下:

hours  | ... | task_assigned  | task_deadline  | task_completion
----------------------------------------------------------------
123    | ... | 2019-08-01     | -              | -
234    | ... | -              | 2018-08-01     | 2019-08-01
145    | ... | 2017-08-01     | 2017-08-01     | 2018-01-01

我想计算每年的总时数,即按年份分组。

当前,我仅考虑task_completion字段。

如果task_completion字段中没有值,则该记录不包含在SUM计算中。

要进一步详细说明,对于year 2019,应同时考虑行11。因此,总小时数应为123 + 234 = 357

对于year 2018,行2 and 3

类似地,对于year 2017,行3

SELECT YEAR(task_completion) as year, ROUND(SUM(total_hours), 2) as hours 
FROM task
GROUP BY year
HAVING year BETWEEN '$year_from' AND '$year_to'

结果集:

year  |  hours
--------------------
2017  |  <somevalue>
2018  |  <somevalue>
2019  |  <somevalue>

我如何也可以包含其他两个日期字段?

3 个答案:

答案 0 :(得分:2)

您希望每一年都考虑一次。使用UNION来获得以下年份:

select year, round(sum(total_hours), 2) as hours
from
(
  select year(task_assigned) as year, total_hours from task
  union
  select year(task_deadline) as year, total_hours from task
  union
  select year(task_completion) as year, total_hours from task
) years_and_hours
group by year
having year between $year_from and $year_to
order by year;

如果您想考虑一年两次或总计三次,则将UNION更改为UNION ALL

答案 1 :(得分:1)

基本上,您想取消数据显示。我将假设" #yourdivid"代表一个-值,而您的日期是真实日期。

NULL

根据您的示例数据,select year(dte) as year, sum(total_hours) as hours from ((select task_assigned as dte, total_hours from task ) union all (select task_deadline, total_hours from task ) union all (select task_completion, total_hours from task ) ) d where dte is not null group by year(dte) order by year(dte); 不是必需的,因此我将其删除。

如果要过滤特定年份,则过滤应放在round()子句中-这样它将过滤聚合之前 的数据。

where更改为:

where

或:

where year(dte) >= ? and year(dte) <= ?

传递日期。

where dte >= ? and dte <= ? 用于参数占位符。了解如何使用参数而不是查询字符串。

答案 2 :(得分:0)

此答案对更新后的请求无效。

<罢工> 如果我理解正确,如果task_assigned仍然为空,则要使用task_completion。为此使用COALEASCE

SELECT
  YEAR(COALESCE(task_completion, task_assigned)) as year,
  ROUND(SUM(total_hours), 2) as hours
FROM task
GROUP BY year
HAVING year BETWEEN $year_from AND $year_to
ORDER BY year;

(我也不认为您实际上也想使用task_deadline,因为在首先分配任务之前如何完成任务?如果可能发生,则将其包含在其中COALESCE表达式。可能:然后是COALESCE(task_completion,task_assigned,task_deadline)。)