【问题标题】:Find Users who worked for 5 consecutive days with date-range in output查找连续工作 5 天且输出日期范围的用户
【发布时间】:2013-01-09 12:58:48
【问题描述】:

我有一个表格,里面有类似下面的数据

  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。

【问题讨论】:

标签: sql oracle oracle10g group-by


【解决方案1】:
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;

【讨论】:

    【解决方案2】:
    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'

    【讨论】:

      【解决方案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.

      【讨论】:

      • 它给了我零行,这不应该是这样!
      • 不可能。单一条件是where code = 'W'。想想代码是什么。例如我的条件应该在 analityc 函数之前。
      • 对不起,我写错了条件!确实有效..两个答案都有效,但接受了另一个答案,因为它在更短的时间内产生了结果..感谢您的回答!
      【解决方案4】:

      我不确定我是否正确理解了所有内容,但这样的事情可能会让你开始:

      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,因为使用保留字作为列名是个坏主意。

      【讨论】:

      • 在 'where days=5' 行出现错误“days:invalid identifier”
      • @user841311:抱歉,复制和粘贴错误。查看我的编辑和 SQLFiddle 示例
      • 我刚刚遇到了一些这种 sql 不起作用的情况,它给出了错误的结果,特别是当 SQLFiddle 表中没有继续的日期时:sqlfiddle.com/#!4/6c2ac/1
      • 当日期在表格中不连续时,您是否有机会检查为什么这不起作用..
      猜你喜欢
      • 1970-01-01
      • 2021-02-03
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 2018-01-06
      相关资源
      最近更新 更多