2016-07-21 2 views
0

У меня есть таблица подписки, которая выглядит следующим образом. Есть около 1 миллиона уникальных идентификаторов. В таблице указано состояние подписки, когда пользователь начал подписку на услугу, как указано «Суб», и когда она отписана, как указано «Usub».Заполните пропущенные значения в столбце, определяемом самим столбцом, и дате

ID Year Month Status 
A 2014 1  
A 2014 2  
A 2014 3  
A 2014 4 Sub 
A 2014 5  
A 2014 6  
A 2014 7  
A 2014 8 Usub 
A 2014 9  
A 2014 10  
A 2014 11  
A 2014 12  
B 2014 1  
B 2014 2  
B 2014 3  
B 2014 4  
B 2014 5 Usub  
B 2014 6  
B 2014 7  
B 2014 8  
B 2014 9 Sub 
B 2014 10  
B 2014 11  
B 2014 12  
. . .  . 
. . .  . 
. . .  . 

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

ID Year Month Status 
A 2014 1 Usub 
A 2014 2 Usub 
A 2014 3 Usub 
A 2014 4 Sub 
A 2014 5 Sub 
A 2014 6 Sub 
A 2014 7 Sub 
A 2014 8 Usub 
A 2014 9 Usub 
A 2014 10 Usub 
A 2014 11 Usub 
A 2014 12 Usub 
B 2014 1 Sub 
B 2014 2 Sub 
B 2014 3 Sub 
B 2014 4 Sub 
B 2014 5 Usub 
B 2014 6 Usub 
B 2014 7 Usub 
B 2014 8 Usub 
B 2014 9 Sub 
B 2014 10 Sub 
B 2014 11 Sub 
B 2014 12 Sub 
. . .  . 
. . .  . 
. . .  . 

Хотя первая таблица показывает, как пользователи имеют более чем одно изменение статуса, любой идентификатор не обязательно иметь больше чем одно изменение статуса. Однако каждый идентификатор будет иметь хотя бы один статус. то есть. пользователь, подписанный на 2014/8 и никогда не отменивший подписку, будет иметь статус = Sub на 2014/8.

+0

Вы хотите сделать это с ** MySQL ** или с ** Hive **?!? Поскольку обычный SQL не будет делать, вам нужен какой-то процедурный трюк. –

+0

@ Самсон, я хочу сделать это с помощью Hive, но также будет принимать подход mysql. – ohmyan

ответ

0

Вы можете сделать это с помощью процедурного кода, считывая данные по порядку и используя переменную для сохранения «состояния» предыдущей записи (с сбросом на каждый новый идентификатор).
Но SQL is не процедурный.

  • MySQL имеет хранимый язык процедуры, которая поддерживает курсоров к итерацию по строкам из отобранного запроса (Google получит Вас большое количество учебных пособий, как this one взятого наугад)
  • улого 2.0 также имеет вид procedural language extension, но это не является частью самого куста - вы должны запустить свой процедурный скрипт в specific tool (и не все имеют Hive 2.0 в любом случае) - также, Hive запускает распределенные запросы в распределенной файловой системе, поэтому «перетасовка» всех строк на одном клиенте узел, то итерация с помощью однопоточного инструмента звучит очень неуклюже - исследуйте на свой страх и риск
  • Улей также имеет сложный и громоздкий способ: произвольно выполнять произвольный процедурный код (в каждом Mapper или каждом редукторе) с оговоркой TRANSFORM (трюк улей унаследованной и плохо названной функции «Hadoop streaming»); к сожалению the documentation is cryptic(вы бы лучше получить хорошую старую книгу, например, «Программирование Улей» от O'Reilly) и когда вы, наконец, может заставить его работать, хорошо, падение производительности является значительным
  • или, вы можете разработать пользовательских Hive UDF в Java с небольшим поворотом - то есть сохранения состояния из предыдущей строки в Java переменных и использовать его для текущей строки

Теперь , какие процессуальной логики вам необходимо реализовать в пользовательском запросе и пользовательском коде?

  • первое, что вам нужно входной запрос для сортировки по ключу, дата
  • с Улей TRANSFORM или улей UDF, вы также должны DISTRIBUTE BY ключа, так что каждый ключ имеет свою историю обрабатывается как единое целое, в одном узле (в противном случае результаты не имело бы абсолютно никакого смысла!)
  • определить 2 переменные для «PreviousRowKey» и «PreviousRowState»
  • на 1-й строке, или на изменение ключа, затем «PreviousRowState = Усуб» и "PreviousRowKey = currentKey"
  • об изменении состояния, затем «PreviousRowState = currentState» else force «currentState = PreviousRowState»
Смежные вопросы