选择先按一天分组然后按一周分组的小时数

时间:2014-11-05 11:42:02

标签: sql oracle select oracle-apex

Oracle ApEx中的

我有一个这样的表:

CREATE TABLE  "ATTENDANCE_HOURS" 
   ("ID" NUMBER NOT NULL ENABLE, 
    "PERSON_ID" NUMBER, 
    "PROJECT_ID" NUMBER, 
    "FROM_X" DATE NOT NULL ENABLE, 
    "TO_X" DATE NOT NULL ENABLE, 
    "NOTE" VARCHAR2(300), 
    "APPROVED" NUMBER DEFAULT 0 NOT NULL ENABLE, 
    "APPROVAL_NOTE" VARCHAR2(300), 
    "DAY" DATE NOT NULL ENABLE, 
     CONSTRAINT "CHECK_TIMES" CHECK (TO_CHAR(TO_X, 'HH24MI') > TO_CHAR(FROM_X, 'HH24MI')) ENABLE, 
 CONSTRAINT "ATTENDANCE_HOURS_PK" PRIMARY KEY ("ID")
  USING INDEX  ENABLE
   )

注意:我无法更改表格。只是不。 我需要为每个人选择他们每周工作多少小时。我已经选择了一天中的多少小时(感谢StackOverflow),如下所示:

select 
    (MAX("TO_X") - MIN("FROM_X"))*24 - 
    (max(case when PROJECT_ID = 21 then to_x else to_date('01012000','DDMMYYYY') end) -
    max(case when PROJECT_ID = 21 then from_x else to_date('01012000','DDMMYYYY')       end))*24 AS TIME_SPENT
// project id = 21 is break
from #OWNER#.ATTENDANCE_HOURS
GROUP BY DAY

发生在我身上的是按周编号对条目进行分组并将整个内容放入SUM(),但是,它不起作用并且它表示:不是单组组功能。 或许我应该开始玩观点?

3 个答案:

答案 0 :(得分:1)

一周内每个人的总小时数看起来像这样:

select person_id, to_char(day, 'YYYY-WW') as week,
       sum(to_x - from_x) as hours_worked
from #OWNER#.ATTENDANCE_HOURS
group by person_id, to_char(day, 'YYYY-WW')
order by person_id, week;

我不知道项目ID的额外逻辑是什么。你的问题没有解释,所以我把它删除,因为没有必要计算小时数。如果重要,您可以将其重新添加。

答案 1 :(得分:0)

这样的事情(未经测试)?

select person_id
     , trunc(from_x,'iw')                                     first_day_of_iso_week
     , sum((to_x - from_x) * 24)                              all_hours
     , sum((case project_id when 21 then to_x - from_x) * 24) break_hours
  from attendance_hours
 group by person_id        -- for each person
     , trunc(from_x,'iw')  -- for each ISO-week

也许您需要额外的检查约束,告诉to_x和from_x的日期部分应该相同,检查(trunc(from_x)= trunc(to_x))?

编辑:我现在看到你的桌子上还有一个超级DAY专栏。这不是一个好主意,因为你现在必须检查(trunc(day)= trunc(to_x))和trunc(day)= trunc(from_x)。如果可以,请删除day列:它已包含在from_x和to_x列中。

答案 2 :(得分:0)

以下查询为您提供工作小时数减去每个人休息时间的总和(提供项目21表示休息,其他所有工作表示工作):

select person_id, 
  sum(case when project_id = 21 then -1 else 1 end * (to_x - from_x)) * 24
from #OWNER#.ATTENDANCE_HOURS
group by person_id;

如果工作时间超过午夜(甚至超过两天),那么每天这样做可能会非常复杂。只要我们假设from_x和to_x在同一天离开,我们就得到:

select person_id, trunc(from_x),
  sum(case when project_id = 21 then -1 else 1 end * (to_x - from_x)) * 24
from #OWNER#.ATTENDANCE_HOURS
group by person_id, trunc(from_x);

每周得到这个:

select person_id, trunc(from_x, 'IW'),
  sum(case when project_id = 21 then -1 else 1 end * (to_x - from_x)) * 24
from #OWNER#.ATTENDANCE_HOURS
group by person_id, trunc(from_x, 'IW');
编辑:哦,我只是注意到我不太了解你的数据。项目出勤时间是从上午9点到上午11点,从上午10点到上午10点15分还有休息时间吗?然后我的查询工作。或者那是两个项目的出席,一个是从上午9点到上午10点,另一个是从上午10:15到上午11点?那么你需要sum(case when project_id = 21 then 0 else to_x - from_x end) * 24代替。

编辑:好的,正如您在评论中所说,project_id = 21不能重叠,只需将其从查询中排除:

select person_id, trunc(from_x, 'IW'), sum(to_x - from_x) * 24
from #OWNER#.ATTENDANCE_HOURS
where project_id <> 21 
group by person_id, trunc(from_x, 'IW');