티스토리 뷰

반응형

hive 에서는 string, bigint, double, decimal 같은 일반적인 primitive 데이터 타입이외에 map, struct, array 같은 complex type 을 지원한다. 테스트용 쿼리를 만들때 primitive 타입의 경우 쉽게 표현이 가능한데 complext type 을 표현하는 방법은 종종 헛갈릴때가 많아서 간단히 표현법을 다루고자 한다.

 

hive 에서는 기본적으로 "select 값" 형태로 더미 값을 출력해보는게 가능한데, complext type 을 선언하여 보는건 아래와 같이 사용하면 된다. 참고로 array 와 같이 N개의 아이템을 풀어서 분석하려면? explode 를 이용해 분석하면 되는데, 그건 아래 글을 참고하도록 하자.

2023.11.27 - [데이터처리/Hive] - [HIVE] Array 필드를 행으로 풀어내는 방법 - explode, posexplode

 

1. array 표현

array() 사이에 아이템을 선언하면 된다. 문자열의 배열이라면 split 함수를 이용해서도 만들어 낼 수 있다.

하지만, 명시적으로 array 타입을 테스트로 생성하기위해서는 아래와 같이 표현하면 된다.

-- ARRAY 표현 : ['홍길동', '둘리']
beeline> select array('홍길동', '둘리');
+---------------+
|      _c0      |
+---------------+
| ["홍길동","둘리"]  |
+---------------+

-- item 을 찾을땐 아래와 같이 표현
select array('홍길동', '둘리')[0];
+------+
| _c0  |
+------+
| 홍길동  |
+------+

-- index 를 벗어나면 NULL
select array('홍길동', '둘리')[3];
+-------+
|  _c0  |
+-------+
| NULL  |
+-------+

 

참고로 split() 을 이용해서 array 문자열을 만들어 낼때 주의할점은 empty array 를 주의해야한다.

만약, split 을 통해 유도할때는 empty string 인 경우는 1개의 아이템이 있는 배열을 리턴한다.

그래서, split 을 통해 배열을 유도할때, empty string 은 array() 를 리턴하도록  if 조건을 넣어야 의도치 않은 1개의 배열이 있는 잘못된 배열을 생성하지 않는다.

-- split 을 통해 만들면 array 에 아이템 1개가 존재한다. (주의)
select split("", ",");
+-------+
|  _c0  |
+-------+
| [""]  |
+-------+

select size(split("", ","));
+------+
| _c0  |
+------+
| 1    |
+------+



-- array() 로 만들면 0개의 아이템인 배열을 만들수 있다.
select array();
+------+
| _c0  |
+------+
| []   |
+------+

select size(array());
+------+
| _c0  |
+------+
| 0    |
+------+

 

 

2. map 타입

사실 map 타입과 struct 타입은 비슷한 느낌으로 표현이 가능하지만, 선언된 이후 아이템을 사용하는 방법이 다르다.

map 은 좀더 유연하다. 없는 key 값을 찾더라도 에러나지 않고 NULL 을 리턴한다.

java 에서 map 을 사용하는 느낌과 비슷하다. struct 타입은 뒤에 이야기 하겠지만, java 에서 bean 객체를 이용하는느낌에 더 가깝다.

-- map 표현방법
select map('name', '홍길동', 'age', 17);
+----------------------------+
|            _c0             |
+----------------------------+
| {"name":"홍길동","age":"17"}  |
+----------------------------+

-- map 에서 특정 값 확인
select map('name', '홍길동', 'age', 17)["name"];
+------+
| _c0  |
+------+
| 홍길동  |
+------+

-- 없는 key 를 찾으면 NULL
+-------+
|  _c0  |
+-------+
| NULL  |
+-------+

 

3. struct 표현방법

map 표현과 유사해보이지만, struct 는 미리 정의된 필드만 허용된다.

얼핏보면 java 에서 bean 객체의 getter() 를 통해 값을 리턴받는것 처럼 "필드명.key" 와 같이 아이템을 찾을수 있으며 선언되지 않은 key 를 사용할 경우 오류가 발생된다. 

-- struct 표현방법 (map 표현과 비슷하다)
select NAMED_STRUCT('name', '홍길동', 'age', 17);
+--------------------------+
|           _c0            |
+--------------------------+
| {"name":"홍길동","age":17}  |
+--------------------------+

-- 특정 key 의 아이템 선택방법
select NAMED_STRUCT('name', '홍길동', 'age', 17).name;
+-------+
| name  |
+-------+
| 홍길동   |
+-------+

-- 없는 key 를 선택하면 에러
select NAMED_STRUCT('name', '홍길동', 'age', 17).nokey;
Error: Error while compiling statement: FAILED: RuntimeException cannot find field nokey(lowercase form: nokey) in [name, age] (state=42000,code=40000)

-- map 표현처럼 map[key] 표현을 해도 에러
select NAMED_STRUCT('name', '홍길동', 'age', 17)["name"];
Error: Error while compiling statement: FAILED: SemanticException [Error 10033]: Line 1:7 [] not valid on non-collection types '"name"': struct<name:string,age:int> (state=42000,code=10033)

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함