2014-11-05 45 views
0

的由天,然后再分组小时和我有一个表是这样的:中的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() ,但是,它不起作用,它说:不是一个单组的功能。 或者我应该开始玩意见?

+1

目前还不清楚列的含义。什么定义了一个小时工作?每个项目每人每天有一行吗?你为什么特殊套管项目ID 21? – Ben 2014-11-05 11:45:52

+0

@Ben b/c项目21是不计入工作时间的中断。 – Lea 2014-11-05 12:15:44

回答

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。你的问题没有解释它,所以我把它作为计算小时数的总和去掉了。如果重要,可以将其重新添加。

+0

项目编号是用来区分人们工作的项目,并且有一个特殊项目 - 休息时间,它不会被计入工作小时数。 – Lea 2014-11-05 12:17:50

+1

对此答案+1。但要时刻关注周的使用情况,特别是对于贝宁和年底。例如,您预计像2015-01一样的2015年1月初的to_char(日,'YYYY-WW'),但结果可能是2015 - 52年,因为1月1日属于上一年的最后一周。有点混乱 – Calipso 2014-11-05 13:20:05

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

编辑:我现在看到你在表格中也有一个superflous DAY列。这不是一个好主意,因为您现在必须检查(trunc(day)= trunc(to_x))和trunc(day)= trunc(from_x)。如果可以的话,摆脱day列:它已经包含在你的from_x和to_x列中。

+0

奇怪,你有很多分但没有金牌! – 2014-11-05 11:57:23

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'); 
+0

对不起,我忘了提及!在每个项目上花费的时间不能重叠,所以你描述的第二种方法是正确的。 :) – Lea 2014-11-05 12:23:03

+0

好的,我已经编辑了我的答案,以提供更简单的解决方案。 – 2014-11-05 12:30:54