我有一个这样的表:
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(),但是,它不起作用并且它表示:不是单组组功能。 或许我应该开始玩观点?
答案 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');