[英]Select sum of hours grouped by a day first and then by a week
在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()中,但是,這行不通,它說:不是單組分組函數。 還是我應該開始欣賞風景?
每個人一周的總工作時間如下所示:
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上的額外邏輯是什么。 您的問題沒有解釋,因此我將其刪除,以免計算工時總和。 如果重要的話,您可以重新添加它。
像這樣(未經測試)?
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的日期部分應該相同,check(trunc(from_x)= trunc(to_x))?
編輯:我現在看到您的表中還有一個多余的DAY列。 這不是一個好主意,因為您現在必須檢查(trunc(day)= trunc(to_x))和trunc(day)= trunc(from_x)。 如果可以的話,請刪除“日期”列:它已包含在from_x和to_x列中。
以下查詢為您提供每個人的工作時間總數減去休息時間(提供的項目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');
編輯:哦,我只是注意到我對您的數據不夠了解。 當項目的出勤時間也從上午10點到上午10:15時,可以從上午9點到上午11點嗎? 然后我的查詢工作。 還是那時候要有兩個項目參加者,一個是上午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');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.