Изменить данные, чтобы отразить другую запись в той же группе

#sql #oracle #views #toad

#sql #Oracle #число просмотров #жаба

Вопрос:

У меня есть представление, которое выдает данные следующим образом:

 ---ID-------StartDate---EndDate----Endpoint number-------             
G002S6YE    01/06/2011  31/05/2013  1012427316307
G002W1AY    27/06/2011  30/09/2012  1012427316307
 

Endpoint number обычно отличается для каждой записи. Однако в некоторых случаях, когда это не так (например, в этом примере) Мне нужно изменить EndDate более раннюю запись на день, предшествующий StartDate более поздней записи, поэтому в этом примере данные должны отображаться как:

 ---ID-------StartDate---EndDate----Endpoint number-------             
G002S6YE    01/06/2011  26/06/2011  1012427316307
G002W1AY    27/06/2011  30/09/2012  1012427316307
 

Это основано исключительно на том Endpoint number , чтобы StartDate и EndDate каждой записи не перекрывались.

Это значительно упрощенная версия фактического скрипта, создающего представление, но если бы вы могли показать простой способ достижения того, что я объяснил здесь, это было бы очень ценно.

Комментарии:

1. «Более ранняя» запись определяется исключительно самой ранней датой начала? Что произойдет, если есть 3 записи с одинаковыми endpoint_number ?

2. @X-Zero — Ну, мне в принципе нужно убедиться, что даты не перекрываются

3. О, и если это представление (изначально не совсем уловил это), каков исходный сценарий определения / просмотра таблицы? У нас могут быть гораздо лучшие способы решить эту проблему, обратившись к базовым таблицам (а представления внутри представлений иногда не одобряются).

Ответ №1:

Итак, у вас есть представление V:

 SELECT id, startdate, enddate, endpt
  FROM ...
 

Вы могли бы изменить это на что-то вроде:

 SELECT id, startdate
     , CASE WHEN nextdt IS NULL THEN enddate ELSE nextdt - 1 END enddate, endpt
  FROM (SELECT id, startdate, enddate, endpt
             , LEAD(startdate) OVER (PARTITION BY endpt ORDER BY startdate) nextdt
          FROM  ...)
 

Простой пример, использующий таблицу T вместо представления, с вашими данными плюс третья строка, чтобы проиллюстрировать случай, указанный комментарием X-Zero. Это может быть не то, что вы хотите, так что будьте осторожны. Запрос выдаст вам конечную дату минус один для следующей записи.

 SQL> CREATE TABLE t (ID VARCHAR2(10), sd DATE, ed DATE, ep NUMBER);

Table created
SQL> INSERT INTO t VALUES ('G002S6YE',to_date('01/06/2011','DD/MM/YYYY'), to_date('31/05/2013','DD/MM/YYYY'), 1012427316307);

1 row inserted
SQL> INSERT INTO t VALUES ('G002W1AY',to_date('27/06/2011','DD/MM/YYYY'), to_date('30/09/2012','DD/MM/YYYY'), 1012427316307);

1 row inserted
SQL> INSERT INTO t VALUES ('G002W1AX',to_date('29/06/2011','DD/MM/YYYY'), to_date('30/06/2012','DD/MM/YYYY'), 1012427316307);

1 row inserted

SQL> SELECT id, sd
  2       , CASE WHEN nextdt IS NULL THEN ed ELSE nextdt - 1 END ed, ep
  3    FROM (SELECT id, sd, ed, ep
  4               , LEAD(sd) OVER (PARTITION BY ep ORDER BY sd) nextdt
  5            FROM  t);

ID         SD          ED                  EP
---------- ----------- ----------- ----------
G002S6YE   1/6/2011    26/6/2011   1012427316
G002W1AY   27/6/2011   28/6/2011   1012427316
G002W1AX   29/6/2011   30/6/2012   1012427316