【问题标题】:SUM of TIMEDIFF while comparing two different date ranges比较两个不同日期范围时的 TIMEDIFF 总和
【发布时间】:2020-11-21 09:14:35
【问题描述】:

我有两个 SQL 表。一个包含工作名称。在第二个表中,我有标记到工作的日期时间条目(进出)。

工作表

jobId,  jobName
1       MyJob
2       AnotherJob
3       ThisJob

定时器表

timerId,  timerIn,              timerOut,             jobs_jobId
1         2020-07-30 16:03:00   2020-07-30 16:17:11   1
2         2020-07-30 14:00:00   2020-07-30 15:00:00   3
3         2020-06-30 16:17:12   2020-07-30 16:49:52   1
4         2020-07-30 16:20:00   2020-07-30 16:38:00   2
5         2020-06-24 08:44:00   2020-07-24 11:18:00   3
6         2020-06-30 15:35:00   2020-07-30 16:02:00   1

我当前的查询可以完美地计算当月每个工作的总小时数。

SELECT 
    `jobName`,
    SUM(TIME_TO_SEC(TIMEDIFF(`timerOut`, `timerIn`)) / 3600) AS `thismonthHours`
FROM
    `timers`
        INNER JOIN
    `jobs` ON `jobs`.`jobId` = `timers`.`jobs_jobId`
WHERE
    `timerIn` >= '2020-07-01 00:00:00'
        AND `timerOut` <= '2020-07-31 23:59:59'
GROUP BY `jobName`

输出(基于上面显示的更大样本)

jobName,    thismonthHours
MyJob       81.3484
AnotherJob  9.6500
ThisJob     4.9500

我正在寻找一种在单个查询中输出本月和上月的小时总和的方法,输出应该如下所示

jobName,    thismonthHours, lastmonthHours
MyJob       81.3484         54.8150
AnotherJob  9.6500          68.1425
ThisJob     4.9500          1.2412

【问题讨论】:

  • 我将从jobs 表开始,然后LEFT JOIN 两个子查询,都在timers 上,每个月一个,为每个工作ID 选择SUM(...) (GROUP BY)在那个月。最后,在您的主查询中,您可以检查总和中的 NULL 值,以防您不想显示根本没有运行的作业

标签: mysql datetime join sum mariadb


【解决方案1】:

你可能想的更复杂。您需要考虑一个作业执行跨越两个不同月的可能性,在这种情况下,我们需要分解执行时间。

这里是使用左连接的方法,然后是 least()greatest()。它会动态计算当前月份,因此您无需在月份更改时重写查询:

select 
    j.jobName,
    sum(case when t.timerOut  >= d.dt
        then unix_timestamp(least(t.timerOut, d.dt + interval 1 month)) - unix_timestamp(greatest(t.timerIn, d.dt))
        else 0
    end) / 3600 hours_this_month,
    sum(case when t.timerIn  < d.dt
        then unix_timestamp(least(t.timerOut, d.dt)) - unix_timestamp(greatest(t.timerIn, d.dt - interval 1 month))
        else 0
    end) / 3600 hours_last_month
from (select date_format(current_date, '%Y-%m-01') dt) d
cross join jobs j
left join timers t
    on  j.jobId = t.jobs_jobId
    and t.timerIn  <  d.dt + interval 1 month
    and t.timerOut >= d.dt - interval 1 month
group by j.jobId, j.jobname
order by j.jobId

您没有显示您对实际样本数据的预期结果。 In this db fiddle,这会产生:

职位名称 | hours_this_month | hours_last_month :--------- | ---------------: | ---------------: 我的工作 | 1425.1008333333 | 16.1300000000 另一个工作 | 0.3000000000 | 0.0000000000 这个职位 | 564.3000000000 | 159.2666666667

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-25
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    相关资源
    最近更新 更多