2013-01-25 79 views
1

誰工作的用戶我有一個表有類似下面發現,連續5天,日期範圍內輸出

Emp Date  Code  
    --- -------- ---- 
    E1 11/1/2012 W 
    E1 11/1/2012 V 
    E2 11/1/2012 W 
    E1 11/2/2012 W 
    E1 11/3/2012 W 
    E1 11/4/2012 W 
    E1 11/5/2012 W 

我希望得到一個日期範圍之間的員工列表數據(說的最後3月),連續5天爲代碼W工作,輸出日期範圍。每個員工可以在一天中使用不同的代碼記錄多個記錄。

預期成果是

下面是我試過,但我沒有接近在所有輸出我尋求

SELECT distinct user, MIN(date) startdate, MAX(date) enddate 
FROM (SELECT user, date, (TRUNC(date) - ROWNUM) tmpcol 
     FROM (SELECT user, date 
       FROM tablename 
      where date between to_date('10/01/2012','mm/dd/yyyy') and to_date('10/03/2012','mm/dd/yyyy') 
      ORDER BY user, date) ot) t 
GROUP BY user, tmpcol 
ORDER BY user, startdate; 

如果E1的Emp已連續10天的工作,他應該在兩個日期範圍的輸出中列出兩次。如果E1已連續工作9天(11/1至11/9),則應在11/1至11/9的日期範圍內僅列出一次。

我已經看到了類似的問題,但他們都沒有爲我準備好。我的數據庫是Oracle 10G,沒有PL/SQL。

+1

而且,如果他工作超過連續5天?輸出應該如何? –

+0

@FlorinGhita我編輯了我的問題。我希望明確.. – user841311

+0

考慮http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:247423100346987778 – xQbert

回答

2

我不知道我理解正確的一切,但這樣的事情可能讓你開始:

select emp, 
     sum(diff) as days, 
     to_char(min(workdate), 'yyyy-mm-dd') as work_start, 
     to_char(max(workdate), 'yyyy-mm-dd') as work_end 
from (  
    select * 
    from (
    select emp, 
      workdate, 
      code, 
      nvl(workdate - lag(workdate) over (partition by emp, code order by workdate),1) as diff 
    from tablename 
    where code = 'W' 
    and workdate between ... 
) t1 
    where diff = 1 -- only consecutive rows 
) t2 
group by emp 
having sum(diff) = 5 

SQLFiddle:http://sqlfiddle.com/#!4/ad7ae/3

請注意,我用workdate代替date的,因爲它是一個使用保留字作爲列名的錯誤主意。

+0

獲取錯誤「days:invalid identifier」at line' where days = 5' – user841311

+0

@ user841311:對不起,複製並粘貼錯誤。看到我的編輯和SQLFiddle示例 –

+0

我剛剛遇到一些情況下,這個SQL不起作用,它給出錯誤的結果,特別是當表中沒有延續日期SQLFiddle時:http://sqlfiddle.com/#! 4/6c2ac/1 – user841311

3

你可以從這裏開始:

select 
emp, count(*) over (partition by emp, code order by date_worked range interval '5' day preceding) as days_worked_last_5_days 
from table 
where code='W'; 

的行與days_worked_last_5_days = 5,你搜索的內容。

See this fiddle.

+0

它給我零行,應該不是這樣! – user841311

+0

不能。單一條件是'where code ='W''。想想代碼是什麼。例如我的情況應該在analityc函數之前。 –

+0

對不起,我寫了一個錯誤的條件!確實工作..答案工作,但接受另一個答案bcoz它在較少的時間產生的結果..感謝您的答案! – user841311

0
Select emp, data-5, data from (SELECT EMP, DATA, WORK,lag, lead, row_number() over(PARTITION BY emp--, DATA 
ORDER BY DATA asc) rn 
    FROM (SELECT emp, 
       data, 
       work, 
       LAG (data) OVER (PARTITION BY emp ORDER BY data ASC) LAG, 
       LEAD (data) OVER (PARTITION BY emp ORDER BY data ASC) LEAD 
      FROM (SELECT emp, 
         data, 
         work, 
         ROW_NUMBER() 
          OVER (PARTITION BY emp, data ORDER BY data ASC) 
          rn 
        FROM example) 
     WHERE rn = 1) a 
WHERE a.data + 1 = LEAD AND a.data - 1 = LAG 
) WHERE rn = 5 

哪裏表例子是:

EMP(VARCHAR2),日期, 'W' 或 'F'

0
SELECT * FROM (
SELECT USERID,USEDATE,WRK,RANK() OVER (PARTITION BY USERID,WRK ORDER BY USEDATE) AS RNK1 FROM USER1 )U1 JOIN 
(
SELECT USERID,USEDATE,WRK,RANK() OVER (PARTITION BY USERID,WRK ORDER BY USEDATE) AS RNK2 FROM USER1 )U2 ON U1.USERID=U2.USERID AND U1.RNK1+3=U2.RNK2 AND U2.USEDATE-U1.USEDATE=3;