2013-05-19 33 views
0

我有一個簡單的就業歷史數據庫,我存儲條目ID,用戶ID,他們的工作,開始和結束日期。可能有一些重疊的條目。我需要確定在給定的時間段內沒有給定時間段的休息時間。就業歷史中的差距

所以USER_ID 1有工作經歷像這樣

Marketing - 01/01/2013 to 19/05/2013 
Sales - 01/01/2011 to 01/05/2012 
Admin - 01/01/2010 to 31/12/2010 

我實際存儲的日期爲Unix時間戳。在三年的歷史中,user_id 1的銷售工作和營銷工作之間的休息時間超過6個月。我怎樣才能將這個標記給他們,這樣他們就可以提供這段時間的條目。

回答

0

你要尋找的是這樣的:

<?php 
    $time_allowed = '1 month'; 

    $person = [ 
     [ 
      1305819929, // 19-05-11 
      1337442341 // 19-05-12 
     ], 

     [ 
      1337442341, // 19-05-12 
      1345933614 // 26-08-12 
     ], 

      // almost 4 month gap here - this will result in flagged() getting triggered 

     [ 
      1355935614, // 19-12-12 
      1368978787 // 19-05-13 
     ] 
    ]; 

    $time_allowed = strtotime('now') - strtotime("-{$time_allowed}"); 

    foreach($person as $key => $job) 
    { 
     if(! isset($person[$key + 1])) 
     { 
      if($job[1] !== 'current' && (strtotime('now') - $job[1]) > $time_allowed) 
      { 
       flagged(); 
      } 
     } 
     else 
     { 
      if(($person[$key + 1][0] - $job[1]) > $time_allowed) 
      { 
       flagged(); 
      } 
     } 
    } 

    function flagged() 
    { 
     // user flagged 
    } 

顯然$person會從數據庫中抓住。腳本應該是不言而喻的,

+0

看起來像一個硬編碼的解決方案1案? – Drew

+0

我以爲Dave只要求用戶在下班6個月後就被標記。我會在一秒鐘之內提交我的帖子。 –

+0

你最好這是可怕的! jk – Drew

2

這個問題比看起來更難,因爲你可以在工作經歷中有重疊。事實上,你可以完全在另一個「內部」工作一段時間,或者在任何一端重疊工作。

你在找的是一個與開始日期有差距的結束日期不在另一個就業期間。所以,讓我們用一個相關子查詢的結束日期之後獲得下一個開始日期,如:

 select t.*, 
      (select StartDate 
       from t t2 
       where t2.user_id = t.user_id and 
        t2.StartDate > t.EndDate 
       order by StartDate desc 
       limit 1 
      ) nextStartDate 
     from t 

現在的問題是:是通過覆蓋另一段時期。對於這一點,我將使用一個複雜的where條款:

select t.* 
from (select t.*, 
      (select StartDate 
       from t t2 
       where t2.user_id = t.user_id and 
        t2.StartDate > t.EndDate 
       order by StartDate desc 
       limit 1 
      ) nextStartDate 
     from t 
    ) t 
where not exists (select 1 
        from t t2 
        where t2.StartDate <= t.EndDate and 
         t2.EndDate >= t.nextStartDate 
       ) and 
     (t.EndDate is null or t.EndDate > now()) 

取決於你如何處理重疊,你可能想允許的日期之間的滯後幾天。

這應該返回表中存在空位的所有記錄。在您的示例數據中,今天會返回記錄(2013-05-19)。 「銷售」記錄之後有差距,直到「營銷」位置。 「營銷」將在未來返回,因爲它會在過去結束。

實際上有可能一個間隙會導致多個記錄被返回。這可能發生在有重疊時,我將用數字解釋:(0,10),(5,12),(15,20)。從12/13開始的差距將影響兩個記錄。如果這是一個問題,那麼查詢可以修復,但我首先想到如何解決這個問題會使查詢更加複雜。

大概你也會過濾用戶標識,你可以把它放在最外層的where子句中。

+0

我是否假設第二個代碼拋出的SQL錯誤是'flag'? – Dave

+0

@Dave。 。 。不,這應該會返回表格中所有的記錄,之後會出現間隙。代碼有't2.nextStartDate',應該是't2.StartDate'。我還添加了一個檢查來過濾當前處於活動狀態的記錄。 –

+0

酷,所以零線結果標記錯誤,我可以發回我的用戶填寫他們的細節? – Dave