#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