2016-08-22 2 views
4

Поверьте мне, я пробовал найти удачу для этой проблемы. У меня были MYSQL & Решения SQLServer, а не Oracle, а не конкретный сверток, который мне нужен. Поскольку Cross Apply недоступна в версии Oracle, которую я использую, я попал в дорожный блок.заполнить отсутствующие данные Oracle

Проблема проста для многих из вас.

Начало вселенной для меня составляет 13 месяцев.

Я таблица, которая имеет

CREATE TABLE TBLTESTAUM (
ORDER_NO NUMBER(10,0) NOT NULL ENABLE, 
RECORD_DATE DATE, 
Order_SEQUENCE NUMBER(5,0) NOT NULL ENABLE, 
CLASS NUMBER(3,0)); 

INSERT INTO TBLTESTAUM VALUES (1234, '29-Aug-2015', 34, 459); 
INSERT INTO TBLTESTAUM VALUES (1234, '20-Jun-2016', 35, 877); 
INSERT INTO TBLTESTAUM VALUES (1234, '20-Jun-2016', 37, 877); 
INSERT INTO TBLTESTAUM VALUES (1234, '02-Jul-2016', 39, 122); 
INSERT INTO TBLTESTAUM VALUES (1234, '28-Jul-2016', 40, 122); 
INSERT INTO TBLTESTAUM VALUES (1234, '31-Jul-2016', 41, 311); 
INSERT INTO TBLTESTAUM VALUES (1234, '10-Aug-2016', 42, 311); 
INSERT INTO TBLTESTAUM VALUES (1234, '18-Aug-2016', 44, 110); 
INSERT INTO TBLTESTAUM VALUES (1234, '20-Aug-2016', 45, 110); 

Пожалуйста, обратите внимание:

  1. 20/июля/2015 в первой вставке.
  2. Поле Seq может иметь или не иметь каждое значение. Возможно, некоторые из них отсутствуют. Если вы хотите его использовать.
  3. Not Nullable for Sequence игнорируется.

Так катится 13 месяцев, дает мне 22/07/2015, на сегодня.

Я хочу, чтобы это разбилось в еженедельных ситуациях «КЛАСС», и если на этой неделе ничего не существует, то последний применяемый КЛАСС. Если ничего последнего, то есть это первый экземпляр, затем следующий применяемый класс. До изменения CLASS.

Выход быть -

Order Num WeekDate CLASS 
123   27-Jul-15 459 
123   3-Aug-15 459 
123   10-Aug-15 459 
123   17-Aug-15 459 
123   24-Aug-15 459 
123   31-Aug-15 459 
123   7-Sep-15 459 
Dates and Order Num to continue till next match in TBLTESTAUM is found 
123   20-Jun-16 877 
123   27-Jun-16 122 
123   4-Jul-16 122 
123   11-Jul-16 122 
123   25-Jul-16 311 
123   1-Aug-16 311 
123   8-Aug-16 311 
123   15-Aug-16 110 
123   22-Aug-16 110 

Есть несколько Num заказа. Но я надеюсь, что ваш код будет соответствовать всем. Обращаем внимание:

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

Заранее спасибо.

PS: Я не буду доступен для просмотра ваших ответов на следующие 10 часов. Человек заснул. Но действительно цените любое время, потраченное на это.

+1

Также покажите нам ожидаемый результат и запрос, который вы использовали ранее. – jarlh

+0

Почему вы думаете, что вам нужно боковое соединение ('cross apply')? –

+0

@jarlh Я делал по частям. По какой-то причине форматирование гиперссылки было неправильным. И это дало мне ошибку, говоря неправильное форматирование кода. – SeeWe

ответ

1

Нижеприведенный запрос может сделать то, что вам нужно. Если это не так, пожалуйста, объясните, что отличается от вашего требования. (Пожалуйста, ответьте на вопросы, которые я задал в своем комментарии на ваш вопрос, также).

В этом решении я создаю необходимые дни (сначала по воскресеньям, потому что вы хотите захватить то, что произошло во время текущей недели), а затем меняю их на понедельники в последнем внешнем запросе). Я также генерирую order_no из таблицы, которую вы предоставили, но в реальной реальной ситуации, которая не должна быть необходимой; вы должны иметь таблицу «заказы» с тем же самым order_no, что и первичный ключ, а мой CTE «o» должен вытащить номера заказов из этой таблицы, а не tbltestaum.

Удачи вам!

with 
    w (weekdate) as (
     select trunc(sysdate, 'iw') - 7 * (level - 1) + 6 -- This will generate Sundays 
     from dual 
     connect by level <= 1 + 
        (trunc(sysdate, 'iw') - trunc(add_months(sysdate, -13), 'iw'))/7 
    ), 
    o (order_no) as (
     select distinct order_no from tbltestaum 
    ), 
    prep (order_no, dt, order_sequence, class) as (
     select order_no, record_date, order_sequence, class 
     from tbltestaum 
     union all 
     select order_no, weekdate, null, null 
     from w cross join o 
    ), 
    z (order_no, dt, order_sequence, class) as (
     select order_no, dt, order_sequence, 
       nvl(last_value(class ignore nulls) over (partition by order_no 
                 order by dt, order_sequence), 
        first_value(class ignore nulls) over (partition by order_no 
                 order by dt, order_sequence 
          rows between unbounded preceding and unbounded following)) 
     from prep 
    ) 
select order_no, to_char(dt - 6, 'dd-Mon-yy') as weekdate, class 
from z 
where order_sequence is null 
; 
+0

Это работает для требования, которое я сказал ранее. Но, как я сказал ранее, это будет в следующий понедельник. Я пытаюсь изменить ваш запрос в соответствии с этим. Позвольте мне вернуться, если это не сработает. Но спасибо. – SeeWe

+1

Хорошо, я переписал - в надежде, что это может помочь другим членам Совета, которые могут иметь тот же вопрос в будущем. – mathguy

+1

На самом деле мне не нужно его переписывать. Следующие незначительные изменения необходимы, чтобы подобрать изменения в прошлую неделю в понедельник утром (если все, что происходит в понедельник, будет снято только в конце этой недели): удалите +6 из третьей строки кода и -6 из третья строка снизу. Затем добавьте «nulls first» после order_sequence в разделе «order by» last_value и first_value (прямо перед закрывающей скобкой в ​​обоих случаях). Если вы хотите, чтобы что-то случилось в понедельник, чтобы повлиять на этот понедельник, а не на следующий, это еще проще - удалите только +6 и -6. – mathguy

Смежные вопросы