Как обновить все записи, кроме последней, созданной в течение данной недели (вс - сб)? - PullRequest
0 голосов
/ 12 мая 2019

Цель:

Я пытаюсь обновить все, кроме самой последней записи HR в течение данной недели.

Я написал решение ниже, но какЯ больше рассмотрел функциональность оракула, думаю, он не будет работать.

'ww' позволил бы мне разбивать только на недели - начиная с дня недели, 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

Так что в этом примере я боюсь, что 1 декабря будет считаться его неделей с 'iw'.Я просто хотел бы сохранить / не обновлять запись 1/4 для сотрудника 22 и запись 1/5 для сотрудника 33 и запись 1/2 для сотрудника 44.

И это всего лишьнебольшой снимок данных. Предполагается, что записи будут создаваться гипотетически каждую неделю - на год назад для каждого сотрудника .

Ответы [ 2 ]

2 голосов
/ 12 мая 2019

Я думаю что-то вроде этого:

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')
             );
0 голосов
/ 14 мая 2019

Нумерация недель и, следовательно, конкретные даты в них могут быть представлены спецификацией «WW» или «IW», но ни одна из них не отвечает требованиям OP. «IW» обозначает недели в соответствии со спецификацией даты ISO 8601; «WW» по григорианской системе нумерации. (см. https://en.wikipedia.org/wiki/ISO_week_date). Проблема не в том, чтобы определить недели в требуемый период Sun-Sat. Таким образом, третий вариант необходим, чтобы рассчитать необходимые еженедельные периоды. Проблема вращается вокруг 1-й недели любого данного года, но мы легко находим конечные данные 1-го периода и оттуда начальную дату следующим образом: 1) Сократить дату до года. 2) Резервное копирование 1 день. 3) Найти в следующую субботу. Результат - последний день 1-го периода. 4) Резервное копирование 6 дней до первого дня 1-го периода. Это становится: 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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...