나는 하이브에있는 함수를 찾고 있는데, 그 달에 날짜가 추가됩니다. 예를 들어하이브 기능 : 달 추가 날짜
:
add_month ('2014년 1월 1일', 1) -> '2014년 2월 1일'
add_month ('2013년 12월 1일', 1) -> '2014-01-01'
나는 하이브에있는 함수를 찾고 있는데, 그 달에 날짜가 추가됩니다. 예를 들어하이브 기능 : 달 추가 날짜
:
add_month ('2014년 1월 1일', 1) -> '2014년 2월 1일'
add_month ('2013년 12월 1일', 1) -> '2014-01-01'
일반 UDF (GenericUDF)를 만들 수 있습니다. 당신이 좋아하는 기능을 사용할 수 있습니다
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredJavaObject;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.junit.Test;
public class AddMonthTest {
private final String TEST_DATA = "2014-01-01";
private final AddMonth addMonth = new AddMonth();
ObjectInspector ob = PrimitiveObjectInspectorFactory.javaStringObjectInspector;
ObjectInspector ob1 = PrimitiveObjectInspectorFactory.javaIntObjectInspector;
private final ObjectInspector[]arg = { ob, ob1 };
@Test
public void testAdd1Month() throws Exception {
DeferredJavaObject def1 = new DeferredJavaObject(TEST_DATA);
DeferredJavaObject def2 = new DeferredJavaObject(1);
addMonth.initialize(arg);
DeferredObject[] def = { def1, def2 };
String resultData = addMonth.evaluate(def).toString();
assertThat(resultData, is("2014-02-01"));
}
@Test
public void testAdd12Month() throws Exception {
DeferredJavaObject def1 = new DeferredJavaObject(TEST_DATA);
DeferredJavaObject def2 = new DeferredJavaObject(12);
addMonth.initialize(arg);
DeferredObject[] def = { def1, def2 };
String resultData = addMonth.evaluate(def).toString();
assertThat(resultData, is("2015-01-01"));
}
@Test
public void testSub1Month() throws Exception {
DeferredJavaObject def1 = new DeferredJavaObject(TEST_DATA);
DeferredJavaObject def2 = new DeferredJavaObject(-1);
addMonth.initialize(arg);
DeferredObject[] def = { def1, def2 };
String resultData = addMonth.evaluate(def).toString();
assertThat(resultData, is("2013-12-01"));
}
@Test
public void testSub12Month() throws Exception {
DeferredJavaObject def1 = new DeferredJavaObject(TEST_DATA);
DeferredJavaObject def2 = new DeferredJavaObject(-12);
addMonth.initialize(arg);
DeferredObject[] def = { def1, def2 };
String resultData = addMonth.evaluate(def).toString();
assertThat(resultData, is("2013-01-01"));
}
@Test
public void incorrectInput() throws Exception {
DeferredJavaObject def1 = new DeferredJavaObject("InvalidString");
DeferredJavaObject def2 = new DeferredJavaObject(12);
addMonth.initialize(arg);
DeferredObject[] def = { def1, def2 };
Object resultData = addMonth.evaluate(def);
assertNull(resultData);
}
}
:
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
public class AddMonth extends GenericUDF {
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 2) {
throw new UDFArgumentLengthException("The function add_month(local_date, months_to_add) requires 2 arguments.");
}
ObjectInspector localDateVal = arguments[0];
ObjectInspector monthsToAddVal = arguments[1];
if (!(localDateVal instanceof StringObjectInspector)) {
throw new UDFArgumentException("First argument must be of type String (local_date as String)");
}
if (!(monthsToAddVal instanceof IntObjectInspector)) {
throw new UDFArgumentException("Second argument must be of type int (Month to add)");
}
return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
String localDateVal = (String) ObjectInspectorUtils.copyToStandardJavaObject(arguments[0].get(),
PrimitiveObjectInspectorFactory.javaStringObjectInspector);
IntWritable monthsToAddVal = (IntWritable) ObjectInspectorUtils.copyToStandardJavaObject(arguments[1].get(),
PrimitiveObjectInspectorFactory.javaIntObjectInspector);
LocalDate localDate = null;
try {
localDate = LocalDate.parse(localDateVal, DateTimeFormat.forPattern("yyyy-MM-dd"));
} catch (Exception ex) {
return null;
}
return new Text(localDate.plusMonths(monthsToAddVal.get().toString());
}
@Override
public String getDisplayString(String[] arguments) {
assert (arguments.length == 2);
return "add_month(" + arguments[0] + ", " + arguments[1] + ")";
}
}
테스트 케이스가 정확성을 입증하기 : 여기
은 샘플 UDF입니다CREATE TEMPORARY FUNCTION add_month AS 'AddMonth';
SELECT
add_month ('2014-01-01',1)
FROM
TAB_NAME;
예상 출력 될 것입니다 :
2014-02-01
Text 및 writableInt로 전송할 때 오류가 계속 발생합니다. 어떤 힌트? – user3874377
@ user3874377 코드 및 스택 추적을 게시하십시오. – Ambrish
add_months를 사용할 수 있습니다. 다음을 참조하십시오. https://stackoverflow.com/questions/38221393/how-to-subtract-months-from-date-in-hive –
1 월 31 일에 1 개월을 추가하면 어떻게됩니까? – Mike
내 상황이 더 간단합니다. 예를 들어, 항상 첫 달에 1 개월을 추가해야합니다 (예 : 2014-01-01 -> 2014-02-01; 2013-12-01 -> 2014-01-01 – Marta
표준 SQL에서이 날짜는 'date'2014-01-01 '+ interval'1 'month'입니다. Hive가 SQL 표준을 지원하는지 여부는 알 수 없습니다. –