oracle sum 有限值,额外于其他变量

oracle sum limited value, extra to other variable

查询:

select sum((out_time+0) - (in_time+0))*24 man_hours 
from emp a,time_sheet b 
where a.SUPERVISOR='43561' 
  and a.EMP_ID=b.EMP_ID;

table中的示例数据

emp_id    in_time              out_time
40716   08-07-2016 09:00    08-07-2016 18:00
40716   07-07-2016 09:00    07-07-2016 18:00
40716   06-07-2016 09:00    06-07-2016 18:00
60383   06-07-2016 09:00    06-07-2016 18:00
60383   07-07-2016 09:00    07-07-2016 18:00
41223   07-07-2016 09:00    07-07-2016 18:00
41223   08-07-2016 09:00    08-07-2016 18:00

结果:与上述查询的差值之和为 45

每一行的时间相差 9 小时。

要求:我只想要<=8小时的总结。 >8 小时应为其他值。

当前9*5=45,要求8*5=40,额外5

我试过解码,我得到了一些奇怪的结果,实际上我没有想到任何想法。以正确的方式指出会有所帮助。 谢谢

这是您的基本查询。 每个员工每天都有一行,正常花费的时间和加班时间(如果有的话)。

WITH MY_TABLE AS  -- Dummy data, leave this out on your enviroment
(
SELECT 40716 AS ID, TO_DATE('08-07-2016 09:00', 'DD-MM-YYYY HH24:MI') AS TIME_START, TO_DATE('08-07-2016 18:00', 'DD-MM-YYYY HH24:MI') AS TIME_END FROM DUAL UNION
SELECT 40716, TO_DATE('07-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('07-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL UNION
SELECT 40716, TO_DATE('06-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('06-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL UNION
SELECT 60383, TO_DATE('06-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('06-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL UNION
SELECT 60383, TO_DATE('07-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('07-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL UNION
SELECT 41223, TO_DATE('07-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('07-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL UNION
SELECT 41223, TO_DATE('08-07-2016 09:00', 'DD-MM-YYYY HH24:MI'), TO_DATE('08-07-2016 18:00', 'DD-MM-YYYY HH24:MI') FROM DUAL)
SELECT -- Actual query
  ID,
  LEAST (8, TOTAL_TIME) AS REGULAR_TIME, -- MIN of actual time and 8 hours
  CASE                                   -- If  he worked less than 8 hours,
      -- OT is 0, otherwise actual-8
    WHEN TOTAL_TIME > 8
    THEN TOTAL_TIME - 8
    ELSE 0
  END AS OVER_TIME
FROM
  (
    SELECT
      ID,
      (TIME_END - TIME_START)*24 AS TOTAL_TIME -- Oracle date returns days,
      -- multiply by 24 to have hourse
    FROM
      MY_TABLE
  );

结果如下

ID      REGULAR_TIME    OVER_TIME
40716   8               1
40716   8               1
40716   8               1
41223   8               1
41223   8               1
60383   8               1
60383   8               1

您可以将此查询嵌套在另一个查询下并执行您喜欢的任何操作,例如,按 id 分组,这样您就可以在每个员工的给定时间范围内获得总的定期和随时间推移。

或者总结一下,没有任何分组来满足你原来的要求。

SELECT
  SUM(REGULAR_TIME),
  SUM(OVER_TIME)
FROM(
-- nest previous select
);

这应该让你开始:

WITH
Timesheet_raw (emp_id, in_time, out_time) AS (
  SELECT 40716, '08-07-2016 09:00', '08-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 40716, '07-07-2016 09:00', '07-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 40716, '06-07-2016 09:00', '06-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 60383, '06-07-2016 09:00', '06-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 60383, '07-07-2016 09:00', '07-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 41223, '07-07-2016 09:00', '07-07-2016 18:00' FROM DUAL UNION ALL
  SELECT 41223, '08-07-2016 09:00', '08-07-2016 18:00' FROM DUAL
),
Timesheet (emp_id, in_time, out_time, length_of_shift) AS (
  SELECT
    emp_id
    , TO_DATE(in_time, 'DD-MM-YYYY HH24:MI')
    , TO_DATE(out_time, 'DD-MM-YYYY HH24:MI')
    , (TO_DATE(out_time, 'DD-MM-YYYY HH24:MI') - TO_DATE(in_time, 'DD-MM-YYYY HH24:MI')) * 24
  FROM Timesheet_raw
)
SELECT
  emp_id, LEAST(length_of_shift, 8) regular, GREATEST(length_of_shift - 8, 0) overtime FROM Timesheet
;

请评论,如果这需要调整/进一步的细节。