簡體   English   中英

選擇按小時分組的小時總和,然后按周分組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM