【问题标题】:oracle sum limited value, extra to other variableoracle sum 有限值,额外到其他变量
【发布时间】:2016-11-11 18:20:50
【问题描述】:

查询:

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;

表中的样本数据

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小时应该是其他值。

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

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

【问题讨论】:

  • 这对我来说不太清楚。您能以表格的形式向我们展示示例输入和输出吗?
  • 添加了一些示例数据。感谢您调查它。 :)
  • 你想要什么输出?
  • 如果我及时总结所有差异,那么我得到 63,即 7 行 * 9 差异 = 63,我需要 7 行 *8 并且 >8 应该作为其他值收集。比如 val a=56 和 val b=7。所以63小时应该以这种方式分手。希望理解。

标签: sql oracle plsql oracle11g oracle10g


【解决方案1】:

这应该让你开始:

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
;

如果需要调整/进一步详细信息,请发表评论。

【讨论】:

  • 使用上面的查询成功了,感谢您的努力和时间:)
【解决方案2】:

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

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
);

【讨论】:

  • 如果不需要对输出进行排序/重复数据删除,则首选 UNION ALL 而不是简单的 UNION
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2023-03-18
  • 2012-05-14
相关资源
最近更新 更多