2015-06-12 1 views
0

У меня есть требование установить end_dt в качестве следующих записей effective_dt минус 1 день для данного идентификатора и по умолчанию 9999-12-31 для последнего запись данного идентификатора у свиньи.Apache PIG- установить дату текущей строки как следующую дату записи минус один день для заданного id

вход данных-

id  eff_dt  end_dt 
1 2012-02-28 9999-12-31 
1 2013-03-15 9999-12-31 
1 2014-05-01 9999-12-31 

Требуется result- (заказ по eff_dt, а затем получить следующую запись)

id  eff_dt  end_dt 
1 2012-02-28 2013-02-14 
1 2013-03-15 2014-04-30 
1 2014-05-01 9999-12-31 

Я новичок в апача PIG, обнаружили, что мы можем использовать свинец/лаг , stitch/flatten, но не получая, как использовать его в скрипте для достижения вышеуказанного результата. Я сталкиваюсь с несколькими проблемами.

Issue 1 :- PIG accepts date as chararray. Need to convert eff_dt into date. 
Issue 2 :- want to know syntax for 'date minus 1 day'. 
Issue 3 :- How to use lead lag to get next record and do a minus one day and default if there is no next record. 

Got ниже пример кода с апача сайта свиньи, но не получаю, как преобразовать его, чтобы использовать его в своем использовании case.:-

Чтобы найти запись 3 вперед текущей записи, используя окно между текущей строкой и 3 записью вперед и значением по умолчанию 0.

A = load 'T'; 
B = group A by si; 
C = foreach B { 
    C1 = order A by i; 
    generate flatten(Stitch(C1, Over(C1.i, 'lead', 0, 3, 3, 0))); 
} 
D = foreach C generate s, $9; 

Это эквивалентно утверждению SQL

выберите s, свинец (я, 3, 0) над (разделом б y si порядок по i строк между текущей строкой и 3 следующего) над T;

Любая помощь будет оценена по достоинству.

+0

Идентификаторы все должно быть уникальным, не так ли? И для первой ожидаемой строки результата, end_dt должен быть 2013-03-14, а не 2013-02-14 – glefait

+0

Да, это должно быть 2013-03-14. Никакие идентификаторы не уникальны. Нам нужно сделать расчет для заданного набора id. Ниже приведены более подходящие образцы данных. входные данные- ------------ id eff_dt end_dt 1 2012-02-28 9999-12-31 1 2013-03-15 9999-12-31 1 2014-05- 01 9999-12-31 2 2010-01-10 9999-12-31 2 2011-03-28 9999-12-31 – Nikita

+0

Вы можете отредактировать свой вопрос, это поможет улучшить форматирование. – glefait

ответ

0

У вас есть 3 вопроса, на которые я могу ответить только первые два на данный момент:

Как конвертировать гггг-мм-дд в дату и вычитать день:

dataB = FOREACH data { 
    date = ToDate(eff_dt, 'yyyy-MM-dd'); 
    dayBefore = SubtractDuration(date, 'P1D'); 
    dayBeforeFormated = ToString(dayBefore, 'yyyy-MM-dd'); 

    GENERATE eff_dt, dayBeforeFormated; 
} 

I наконец, имел шанс попробовать метод Сверх и Стиха из копилки. Вот рабочее решение.

-- first load the piggybank and define shorthand to Over and Stitch functions 
REGISTER '/data/lib/piggybank-0.12.0.jar'; 
DEFINE Over org.apache.pig.piggybank.evaluation.Over(); 
DEFINE Stitch org.apache.pig.piggybank.evaluation.Stitch(); 

-- load the input data 
data = LOAD '/data' USING PigStorage('\t') AS (id:int, eff_dt:chararray); 

-- generate the previous date (that could be done later) 
data_before = FOREACH data { 
    date = ToDate(eff_dt, 'yyyy-MM-dd'); 
    dayBefore = SubtractDuration(date, 'P1D'); 
    eff_before = ToString(dayBefore, 'yyyy-MM-dd'); 
    GENERATE id as id, eff_dt as eff_dt, eff_before as eff_before; 
} 

-- Stitch join two bags based on position 
-- Over apply a function on a group. Here we use the lead operator to get the next tuple 
data_over = FOREACH (GROUP data_before ALL) { 
    out = Stitch(data_before, Over(data_before.eff_before, 'lead', 0, 1, 1, '9999-99-99')); 
    GENERATE FLATTEN(out) as (id, eff_dt, eff_before, end_dt); 
} 

-- finally, we output (we could have transform the date here) 
data_final = FOREACH data_over GENERATE id, eff_dt, end_dt; 

Вывод этого сценария:

(1,2012-02-28,2013-03-14) 
(1,2013-03-15,2014-04-30) 
(1,2014-05-01,9999-99-99) 
+0

Спасибо за ответ. Это было полезно. Теперь у меня есть столбец dayBefore для данного идентификатора. Мне нужно знать следующую строку и выбрать значение dayBefore column и поместить ее в мою текущую строку как end_dt. – Nikita

+0

Проверьте обновленное решение;) – glefait

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