2014-09-10 45 views
0

我有一張表來記錄一個人工作的部門以及它開始和結束的日期。用sql- Oracle

如果我定義了一段時間,我怎樣才能爲每個人獲得他/她工作的天數?

例如。

當週期是2014年1月5日和31/07/2014之間(日期格式爲日/月/年)

(id_department, id_person, date_start, date_end) 

Person #856 

190 856 04/07/2014 null 
12 856 17/05/2004 13/06/2008 
6 856 13/06/2008 19/09/2013 
169 856 19/09/2013 03/07/2014 

應返回的天數工作:90天(63 01/05/2014至07/07/2014加27從04/07/2014至31/07/2014)

Person #900 

19 900 30/07/2014 null 
days: 1 

Person #800 

21 800 19/02/2013 05/06/2014 
days: 35 

Person #100 

21 100 24/03/2012 05/05/2014 
days: 4 

以及任意日期組合。是否有可能在一個查詢中獲得總和?

+0

假設這是針對Oracle的,因爲它在標題中。 – 2014-09-10 13:03:21

回答

1

這樣的事情應該工作:

select person_id, 
SUM(case 
     when 
     date_start >= to_date('01/05/2014','dd/mm/yyyy') 
     and date_end <= to_date('31/07/2014', 'dd/mm/yyyy') 
     then (date_end - date_start) 
     when 
     to_date('01/05/2014','dd/mm/yyyy') > date_start 
     and to_date('31/07/2014', 'dd/mm/yyyy') < date_end 
     then (to_date('31/07/2014','dd/mm/yyyy') - to_date('01/05/2014','dd/mm/yyyy')) 
     when 
     to_date('01/05/2014','dd/mm/yyyy') < date_start 
     and to_date('31/07/2014', 'dd/mm/yyyy') < date_end 
     then (to_date('31/07/2014','dd/mm/yyyy') - date_start) 
     when 
     to_date('01/05/2014','dd/mm/yyyy') > date_start 
     and to_date('31/07/2014', 'dd/mm/yyyy') > date_end 
     then (date_end - to_date('01/05/2014','dd/mm/yyyy')) 
     else 0 
    end) 
as days 
from table_name 
group by person_id 
+1

這裏的問題是,如果一個人在01/05/2014之前開始並且在2014年7月31日之後結束,那麼這些條款將消除這筆款項,這應該是90天 – gbvisconti 2014-09-10 12:28:24

+0

我編輯了答案,我希望oracle知道'在'sum()'中。我做了 – 2014-09-10 12:38:34

+0

,但大部分行都返回零。我試圖改變一下這個查詢,這會有很大幫助 – gbvisconti 2014-09-10 12:49:33

1

這是一個非常簡單的方法:

with dates as (
     select date '2014-05-01' as PeriodStart, date '2014-07-31' as PeriodEnd 
     from dual 
    ) 
select p.*, 
     (case when p.date_end >= dates.PeriodStart and p.date_start <= dates.PeriodEnd 
      then least(dates.PeriodEnd, p.date_end) - greatest(dates.PeriodStart, p.date_start) 
     end) as DaysInPeriod 
from dates cross join 
    persons p; 

注意這個使用Oracle的約會一定的標準(在date關鍵字其次是ISO標準YYYY -MM-DD格式)。你可以用你喜歡的任何格式輸出日期,但是當你在數據庫中使用它們時,你應該使用原生格式。

+0

一個問題,我想你應該改變的條件'當p.date_end > = dates.PeriodStart或p.date_start <= p.PeriodEnd'。因爲AND將僅考慮開始日期和結束日期都在指定時間段之間的情況。 – CodeNewbie 2014-09-10 13:15:19

+0

@CodeNewbie。 。 。不,'和'是正確的(「PeriodEnd」上的別名是錯誤的,但這是另一回事)。兩個時段重疊,一個在第二個結束之前開始,第二個結束在第二個結束之後開始。 – 2014-09-10 13:31:21

+0

你是對的。我很抱歉。我沒有看到你比較了p.date_end和dates.PeriodStart,反之亦然。你的回答很好。 – CodeNewbie 2014-09-10 13:40:56