1

我有一个表有类似于下面的数据

  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 个月)之间连续为代码 W 工作 5 天的员工列表,输出中的日期范围。每个员工在一天内可以有多个不同代码的记录。

预期输出是

Emp   Date-Range 
---   ----------
 E1   11/1 -11/5

以下是我尝试过的,但我根本没有接近我寻求的输出

 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;

如果 Emp E1 连续工作了 10 天,他应该在两个日期范围的输出中列出两次。如果 E1 连续工作了 9 天(11/1 到 11/9),他应该只列出一次,日期范围为 11/1 到 11/9。

我已经看到了类似的问题,但没有一个问题完全适合我。我的数据库是 Oracle 10G,没有 PL/SQL。

4

4 回答 4

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 的行就是您搜索的内容。

看到这个小提琴。

于 2013-01-25T14:56:30.360 回答
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使用保留字作为列名是一个坏主意。

于 2013-01-25T14:45:07.077 回答
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”

于 2013-01-25T16:06:32.917 回答
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;
于 2017-01-05T08:33:44.047 回答