2016-07-04 2 views
0

Это мой 1-й пост на форуме. Обычно я мог найти то, что мне нужно, но, честно говоря, я не совсем уверен, как задать правильный вопрос. Поэтому, пожалуйста, примите мои извинения, если на форуме уже есть ответ, и я пропустил его.Oracle SQL-Flag записи на основе даты записи против истории

Я бегу следующий код в базе данных Oracle с помощью донного Software:

SELECT 
T1."REGION" 
, T1."COUNTRY" 
, T1."IDNum" 
, T1."CUSTOMER" 
, T1."BUSSINESS" 
, T3."FISCALYEARMONTH" 
, T3."FISCALYEAR" 
, SUM(T4."VALUE") 
,"HISTORICAL_PURCHASE_FLAG" 

FROM 
"DATABASE"."SALES" T4 
, "DATABASE"."CUSTOMER" T1 
, "DATABASE"."PRODUCT" T2 
, "DATABASE"."TIME" T3 

WHERE 
T4."CUSTOMERID" = T1."CUSTOMERID" 
AND T4."PRODUCTID" = T2."PRODUCTID" 
AND T4."DATEID" = T3."DATEID" 
AND T3."FISCALYEAR" IN ('2016') 
AND T1."COUNTRY" IN ('ENGLAND', 'France') 


GROUP BY 
T1."REGION" 
, T1."COUNTRY" 
, T1."IDNum" 
, T1."CUSTOMER" 
, T1."BUSSINESS" 
, T3."FISCALYEARMONTH" 
, T3."FISCALYEAR" 
; 

Этот запрос дает мне информацию о сделках. Как вы можете видеть выше, я хотел бы добавить столбец с именем «HISTORICAL_PURCHASE_FLAG».

Я бы хотел, чтобы запрос взял ЗАКАЗЧИК и FISCALYEARMONTH. Затем я хотел бы проверить, есть ли какие-либо транзакции, зарегистрированные для ЗАКАЗЧИКА, до двух лет в прошлом.

Так позволяет сказать, что я получаю следующий результат:

LineNum REGION COUNTRY IDNum CUSTOMER   BUSSINESS  FISCALYEARMONTH FISCALYEAR VALUE  HISTORICAL_PURCHASE_FLAG 
1  Europe ENGLAND 255  Abraxo Cleaner Co. Chemicals  201605   2016  34,567.00 
2  Europe FRANCE 123  Metal Trade   Heavy   201602   2016  12,500.00 
3  Europe ENGLAND 255  Abraxo Cleaner Co. Chemicals  201601   2016  8,400.00  

LineNum 1 показывает сделку по Abraxo уборщик Co. зарегистрирована на 201605. И LineNum 3 также для Abraxo чистого Co., но зарегистрированные на 201601. Что я потребуется выполнить запрос, должен обозначить LineNum 1 как «Существующий». Потому что была зарегистрирована предыдущая транзакция.

С другой стороны, LineNum 3 был зарегистрирован впервые для Abraxo Cleaner Co., поэтому строка будет помечена как «Новая».

Подводя итог, я хотел бы, чтобы каждая строка данных обрабатывалась индивидуально. И проверить, есть ли какие-либо предыдущие записи данных для CUSTOMER & FISCALYEARMONTH - 24 месяца.

Заранее благодарю за помощь.

+0

есть несколько способов сделать это. У вас может быть подзапрос для извлечения данных для нового столбца, или мой предпочтительный метод будет заключаться в создании функции, которая делает тяжелый подъем, и называть это как часть SELECT. Вы также можете сделать что-то с операторами CASE, но это усложнит. Кроме того, ваш столбец financial_year действительно является строкой?числовое значение будет лучше. – davegreen100

+0

«2 года в прошлом» от настоящего времени или от FISCALYEARMONTH? – Mottor

+0

Запрос сужает транзакции с 2016 года только для этих стран: 'AND T1." COUNTRY "IN ('ENGLAND', 'France')'. Вы хотите проверить, есть ли какие-либо предыдущие записи ** ** только для этих двух стран ** или для любой страны <> ENGLAND & FRANCE? – krokodilko

ответ

0

Вы можете использовать LAG функции:

SELECT 
"REGION" 
, "COUNTRY" 
, "IDNum" 
, "CUSTOMER" 
, "BUSSINESS" 
, "FISCALYEARMONTH" 
, "FISCALYEAR" 
, SUM("VALUE") 
, MAX(CASE WHEN to_date(prev_fym,'YYYYMM') >= ADD_MONTHS (to_date("FISCALYEARMONTH",'YYYYMM'), -24) THEN 'Existing' 
      ELSE NULL END) "HISTORICAL_PURCHASE_FLAG" 
FROM 
(
    SELECT 
    T1."REGION" 
    , T1."COUNTRY" 
    , T1."IDNum" 
    , T1."CUSTOMER" 
    , T1."BUSSINESS" 
    , T3."FISCALYEARMONTH" 
    , T3."FISCALYEAR" 
    , T4."VALUE" 
    , LAG ("FISCALYEARMONTH", 1) OVER (PARTITION BY T1."IDNum" ORDER BY T3."FISCALYEARMONTH" DESC) prev_fym 
    FROM 
    "DATABASE"."SALES" T4 
    , "DATABASE"."CUSTOMER" T1 
    , "DATABASE"."PRODUCT" T2 
    , "DATABASE"."TIME" T3 
    WHERE 
    T4."CUSTOMERID" = T1."CUSTOMERID" 
    AND T4."PRODUCTID" = T2."PRODUCTID" 
    AND T4."DATEID" = T3."DATEID" 
    AND T1."COUNTRY" IN ('ENGLAND', 'France') 
    AND T3."FISCALYEAR" IN ('2014','2015','2016') 
) 
WHERE "FISCALYEAR" IN ('2016') 
GROUP BY 
"REGION" 
, "COUNTRY" 
, "IDNum" 
, "CUSTOMER" 
, "BUSSINESS" 
, "FISCALYEARMONTH" 
, "FISCALYEAR" 
; 
+0

Этот запрос не может работать, поскольку исходный запрос фильтрует все годы, кроме 'AND T3. 'FISCALYEAR" IN (' 2016 ') ', поэтому результат подзапроса содержит нет данных за предыдущие годы. – krokodilko

+0

@kordirko У вас есть право – Mottor

+0

@kordiko Отремонтировано. Не могу проверить. – Mottor

0

Использование упрощенной «входную» таблицы ... Вы можете использовать LAG() аналитической функции и состояние сравнения, чтобы заполнить ваш последний столбец. Я предполагаю, что ваш fiscalyearmonth является числом - если это поле персонажа, оберните fiscalyearmonth в пределах TO_NUMBER(). (Было бы намного лучше, если бы вы сохранили их как настоящие даты Oracle, возможно, date 2016-06-01 вместо 201606, но я работал с тем, что у вас есть в настоящее время ... и воспользовался тем, что в числовом формате «24 месяца назад» просто означает " вычесть 200 ").

with inputs (linenum, idnum, fiscalyearmonth) as (
     select 1, 255, 201605 from dual union all 
     select 2, 123, 201602 from dual union all 
     select 3, 255, 201601 from dual union all 
     select 4, 255, 201210 from dual 
    ) 
select linenum, idnum, fiscalyearmonth, 
     case when fiscalyearmonth 
       - lag(fiscalyearmonth) 
          over (partition by idnum order by fiscalyearmonth) < 200 
      then 'Existing' else 'New' end   as flag 
from inputs 
order by linenum; 


    LINENUM  IDNUM FISCALYEARMONTH FLAG 
---------- ---------- --------------- -------- 
     1  255   201605 Existing 
     2  123   201602 New 
     3  255   201601 New 
     4  255   201210 New 
0

Другим решением может быть внешним соединение «БАЗА». «ПРОДАЖИ» T4 второй раз, как T5, wilter финансового года через КУДА < t4.FiscalYear-2. Если столбец равен NULL, запись является новой, если внешнее соединение приводит к значению, запись является исторической.

0

Вы можете достичь с помощью функции row_number(), как показано ниже ... изменить в соответствии с вашими потребностями ... Я предполагал, что 2 года (означает предыдущие 24 месяца с sysdate). Вы можете запускать подзапросы отдельно, чтобы проверить, как он работает.

Select 
"REGION" 
,"COUNTRY" 
,"IDNum" 
,"CUSTOMER" 
,"BUSSINESS" 
,"FISCALYEARMONTH" 
,"FISCALYEAR" 
,"VALUE" 
, (case when (TXNNO = 1 or TOTAL_TXN_LAST24MTH = 0) then 'New' else 'Existing' end) as "HISTORICAL_PURCHASE_FLAG" -- if no txn in last 24 month or its first txn then 'new' else 'existing' 
from 
(
    select 
    SubQry."REGION" 
    , SubQry."COUNTRY" 
    , SubQry."IDNum" 
    , SubQry."CUSTOMER" 
    , SubQry."BUSSINESS" 
    , SubQry."FISCALYEARMONTH" 
    , SUBQRY."FISCALYEAR" 
    , SUBQRY."VALUE" 
    , ROW_NUMBER() over (partition by SUBQRY."REGION",SUBQRY."COUNTRY",SUBQRY."IDNum",SUBQRY."CUSTOMER",SUBQRY."BUSSINESS" order by SUBQRY."FISCALYEARMONTH") as TXNNO, 
    , SUM(case when (TO_NUMBER(TO_CHAR(sysdate,'YYYYMM')) - SUBQRY."FISCALYEARMONTH") < 24 then 1 else 0 end) as TOTAL_TXN_LAST24MTH 
    From 
    (
    SELECT 
    T1."REGION" 
    , T1."COUNTRY" 
    , T1."IDNum" 
    , T1."CUSTOMER" 
    , T1."BUSSINESS" 
    , T3."FISCALYEARMONTH" 
    , T3."FISCALYEAR" 
    , SUM(T4."VALUE") as VALUE 
    FROM 
    "DATABASE"."SALES" T4 
    , "DATABASE"."CUSTOMER" T1 
    , "DATABASE"."PRODUCT" T2 
    , "DATABASE"."TIME" T3 
    WHERE 
    T4."CUSTOMERID" = T1."CUSTOMERID" 
    AND T4."PRODUCTID" = T2."PRODUCTID" 
    AND T4."DATEID" = T3."DATEID" 
    AND T3."FISCALYEAR" IN ('2016') 
    AND T1."COUNTRY" IN ('ENGLAND', 'France') 
    GROUP BY 
    T1."REGION" 
    , T1."COUNTRY" 
    , T1."IDNum" 
    , T1."CUSTOMER" 
    , T1."BUSSINESS" 
    , T3."FISCALYEARMONTH" 
    , T3."FISCALYEAR" 
) SUBQRY 
); 
Смежные вопросы