如何更新给定一周(星期日至星期六)内创建的最新记录以外的所有记录?

时间:2019-05-12 01:08:25

标签: sql oracle date plsql

目标:

我正在尝试在给定的一周内更新除最新的HR记录以外的所有记录。

我已经在下面编写了解决方案,但是随着我对oracle date功能的更多了解,我认为它不起作用。

'ww'只允许我在几周内进行分区-从工作日1月1日开始。

'iw'会更近一些,但新的一年将拆分周,并且如果新年从中旬开始,则DEC的最后一周将有记录。

但是,我只需要除了最近的记录之外的所有内容-该周内(星期日-星期六)已更新。

这是到目前为止我尝试过的事情。:

   UPDATE hr_info.hr_hours
      SET expire_date = SYSDATE, deleted = 'Y', update_date = SYSDATE
    WHERE (ROWID, compnay_id) IN (SELECT ROWID, compnay_id
                                  FROM (SELECT hrs.*,
                                               ROW_NUMBER ()
                                               OVER (
                                                  PARTITION BY emp_nbr,
                                                               TO_CHAR (
                                                                  hrs_effective_date + 1,
                                                                  'iw'),
                                                               TO_CHAR (
                                                                  hrs_effective_date,
                                                                  'yy')
                                                  ORDER BY
                                                     hrs_effective_date DESC)
                                                  rown
                                          FROM hr_info.hr_hours hrs
                                         WHERE     compnay_id = 3
                                               AND expire_date =
                                                      TO_DATE ('12/31/9999',
                                                               'mm/dd/yyyy'))
                                 WHERE    rown > 1;

   COMMIT;

请求的示例数据:

enter image description here

因此,在此示例中,恐怕12月1日会以'iw'算作它自己的一周。 我只想保留/不更新员工22的1/4记录和员工33的1/5记录,以及员工44的1/2记录。

而且,这只是数据的小快照。假设 每周都会创建记录-每位员工都可以追溯到几年前

2 个答案:

答案 0 :(得分:2)

我在想这样的事情:

UPDATE hr_info.hr_hours h
    SET expire_date = SYSDATE,
        deleted = 'Y',
        update_date = SYSDATE
    WHERE h.hrs_effective_date < (
              SELECT MAX(h2.hrs_effective_date)
              FROM hr_info.hr_hours h2
              WHERE h2.company_id = h.company_id AND
                    TRUNC(hr2.hrs_effective_date, 'IW') = TRUNC(hr.hrs_effective_date, 'IW')
             );

答案 1 :(得分:0)

周编号及其中的特定日期可以表示为“ WW”或“ IW”规范,但都不符合OP要求。 “ IW”代表根据ISO 8601日期规范的星期;根据公历周编号系统,为“ WW”。 (请参阅https://en.wikipedia.org/wiki/ISO_week_date),问题在于无法确定所需的周六周数。因此,需要第三个选择,那就是计算必要的每周时间。麻烦围绕任何一年的第一个星期,但是我们很容易找到第一个时期的结束数据,从那里开始的日期如下:1)将日期截断到年份。 2)备份1天。 3)找到下一个星期六。结果是第一个期间的最后一天。 4)备份6天到第一个期间的第一天。变成: select next_day(trunc(sysdate,'yyyy')-1,'sat') - 6; 5)现在,我们可以根据需要计算任意多个星期六至日的日期范围。 有了它,只需找到每个期间内的最大日期并更新其他行即可。

update hr_hours
   set deleted='Y'
     , update_date = sysdate
     , expire_date = sysdate
 where 1=1
   and expire_date = date '9999-12-31'
   and (employee_nbr,hrs_effective_date) not in 
(with date_range as (select date '2019-01-04' sdt, date '2019-03-01' edt from dual)            -- get full date range
   , weeks as (select level-1 wk from dual connect by level <= (select trunc( (edt-sdt)/7)+1 from date_range)) -- calc number of weekly periods
   , yr1st as (select next_day(trunc(sdt,'yyyy'), 'Sat') - 6 p1_start from date_range) -- calculate 1st preiod start date
   , periods as (select p1_start+(7*wk) period_begin, p1_start+(7*wk)+6 period_end from yr1st, weeks) -- calculate each period start and end date
select employee_nbr, eff_date
 from (
select h.employee_nbr,max(h.hrs_effective_date) eff_date,p.period_begin
  from hr_hours h
     , periods  p
 where 1 = 1
   and h.hrs_effective_date between p.period_begin and p.period_end
 group by h.employee_nbr,p.period_begin));