2017-04-20 2 views
2

색조에서 하나의 하이브 테이블의 합계 함수를 실행하고 NaN의 반환 값을 가져옵니다. 그것은 나에게 NaN의 결과를주는 이유를 모르겠어요하이브에서 NaN 값을 가진 행을 필터링하는 방법은 무엇입니까?

select sum(v1) from hivedb.tb1;

:

여기 내 코드입니다. 내 V1 값 중 하나가 null의 경우 내가 확인 :

select * from hivedb.tb1 where v1 is null;

를, 그리고 null 값을 가지고 어떤 기록을 밝혀 없습니다. 표에는 1 억 개의 행이 있으므로 각 레코드에 대한 수동 확인을 수행 할 수 없습니다.

  1. 아무도 왜 NaN 결과를 얻는 지 알고 있습니까?
  2. 그리고 일부 행에 일부 비정상적인 값이 있기 때문에 어떻게 찾을 수 있습니까?

도움을 주시면 감사하겠습니다. 미리 감사드립니다.

업데이트 1 수동으로 첫 번째 1000 개의 행을 스크리닝하고 tb1에 NaN의 비정상적인 값을 찾아 냈습니다. 이전 단계의 반올림 오류로 인해 발생합니다. 그래서 제 질문 1이 대답 될 것입니다. 다른 이유가있을 수 있다고 생각되면 자유롭게 의견을 말하십시오.

효율적인 방법으로 NaN 값을 가진 행을 찾는 방법을 여전히 모르겠습니다. 그래서 나는 아직도 내 질문 # 2에 대한 답변을 기다리고있다. 언제든지 공유하십시오. 도와 주셔서 감사합니다.

업데이트 2 아래의 토론 섹션에서 허용되는 답변에서 문제가 해결되었습니다. 여러 가지 방법으로 처리 할 수 ​​있습니다.

  1. v1 + 1> v1의 조건 선택을 사용하십시오. NaN이 아닌 값이있는 행을 선택합니다.
  2. cast (v1 as String) = 'NaN'의 조건 선택을 사용하십시오. NaN 값을 가진 행을 선택합니다.
+0

아, 어서, SQL 집계를 계산할 때 Null 값은 무시됩니다. 반면에 1 억 개의 값의 합계가 Integer 또는 Float 또는 Decimal (p, s)의 용량을 오버플로 할 수 있습니다. 그건 그렇고,'v1'의 데이터 타입은 무엇입니까? 그리고 당신은'sum (cast (v1 as Double))'을 시도 했습니까? –

+0

@Samson Scharfrichter 네 말이 맞아. 난 그냥 비정상적인 행을 선택하는 방법을 모르겠습니다. 그래도 나머지는 고맙다. 질문에 다시, v1은 두 배입니다. – Counter10000

+0

@SamsonScharfrichter 감사합니다. 나는 그것을 알아낼지도 모른다. 우연히, 수천 개의 행을 수작업으로 검사하고 운 좋게도 NaN 값을 tb1에 두었습니다. 반올림 오류로 인해 생성됩니다. 그래서 내 첫 번째 질문은 좀 대답, 이는 tb1에 존재하는 NaN 값입니다. 그러나 나는 아직도 나의 질문 # 2를 다루는 방법을 모른다. 통찰력이 있다면 언제든지 공유하십시오. – Counter10000

답변

2

으로 NaN이 처리 할 수 ​​및 Java는 숫자 의미에 대한 IEEE 표준 수여됩니다. 그 말은 ... NaN은 까다 롭습니다. that post을 인용

...

(Float.NaN == Float.NaN)는 항상 false를 반환합니다. 당신이 Float.isNaN()의 JDK 구현 보면 경우가 (숫자 자체가 동일해야 때문에 의미가있는) 그 자체 같지 않으면
는 사실, 숫자가 숫자가 아닌 값이다.
Double은 동일합니다.

NaN이

그래서, 즉

where v1 is not null and not reflect2(v1, "isNaN") 

, 어떻게 하이브 열을 원시 자바 메소드를 호출 할 수 있습니다 reflect2를 호출 (문서화되지 않은) 하이브 기능을 사용하는 방법을 보여주는 의미가 없습니다 .. .because - 이론 - 당신은 단순히 국가 수 :

where v1 is not null and v1=v1 

면책 조항 - 내가 본 건 어디 일 하이브 최적화 프로그램은 공격적인 "최적화"를 만들어 잘못된 결과를 만들어냅니다. 간단한 v1=v1 절은 예상대로 NaN의 값을 필터링하지 않는 경우 즉
은 다음

에게 ... reflect2로 편집 봐 - 참, 최적화 알고리즘은 일부에서 v1=v1 절을 무시 나타납니다 하이브 버전 (설명 참조) 그래서 더 악독 수식이 필요하다 : 오류를 반올림하는 경우를 제외하고는

  • v1 +1.0 > v1이 ... 작업을해야 할 하나 abs(v1) < < 1 abs(v1) >> 1
  • 다른 "숫자"트릭은 결국 v1 =0.0

이, 가장 강력한 방법은 (cast(v1 as String) <>'NaN'시도 가능한 모든 때문에 나타납니다 특히, 가장자리의 경우 유사 실패 NaN 값은 비록 산술적 의미에서 정확히 "같음"이 아니더라도 "NaN"으로 표시됩니다..


사이드 노트에 대한 reflect2-reflect의 (a specific Wiki entry을 가지고도 등) 언급하는 동안, 그것은 참으로 the official Hive doc에 언급되지 않은 것을 볼 수 있습니다. 그러나 하이브리드 V0.11 cf에서 이미 구현되었습니다. Hive-4025

편집 - 자바 "반사"가 이제 ODBC/JDBC/색조 연결 (주석 참조) 기본적으로 비활성화되어, 보안 플러그인 등을 사용하면 다시 사용할 수 없습니다 레인저 또는 센트리로서. 따라서 사용법은 (권장되지 않는) hive CLI로 제한됩니다.

+0

안녕하세요, @ Samson Scharfrichter : 친절한 메모를 가져 주셔서 감사합니다. 불행히도, 둘 다 작동하지 않습니다. 나는 v1 = v1과 v2를 모두 시험해 보았습니다. v1 = v1 테스트의 경우 오류는 없었지만 잘못된 결과가 나옵니다. 다음은 2를 반영한 ​​오류 메시지입니다.'문 컴파일 중 오류 발생 : FAILED : SemanticException UDF reflect2가 허용되지 않습니다. ' – Counter10000

+0

Cf. https://community.hortonworks.com/questions/25828/udf-reflect-is-not-allowed-beeline.html JDBC를 통해 'reflect'및 'reflect2'에 대해 'black-listed'에 대한 정보를 제공합니다. 에지 노드에서 기존의 하이브 (hive) 팻 클라이언트를 사용해 볼 수 있습니까? –

+1

예를 들어'(v1 +1.0> v1 또는 abs (v1) * 1.1> abs (v1))'과 같이'v1 = v1'보다 복잡한 것을 시도 했습니까? _ (v1이 10^-38, 10^+ 38 범위에 없으면 +1 트릭이 계속 작동하지 않으며 * 1.1 트릭은 0으로 작동하지 않지만 함께하면 작업을 수행 할 수 있습니다. 비효율적 인 방식) _ –

1

당신은 하이브 자바 (플러스 널위한 SQL 고유의 의미와 친구)에 의존

SELECT SUM(CAST(IF(v1 ='NaN', 0, v1)) as Double) FROM hivedb.tb1 
+0

당신의 제안을 시도해 보았고,이 결과를 얻었습니다.'AnalysisException : DOUBLE 타입과 STRING 타입의 피연산자는 비교할 수 없습니다 : x = 'NaN'' – Counter10000

+0

잘못된 방향으로'cast()'를 얻었고, _NaN_가 수많은 개념적 이유 때문에 0이 아닌 _Null_로 처리됩니다. 그래서 당신은'sum (cast (v1 as String) = 'NaN', Null else v1 end의 경우)와 같은 sthg에 대한 후속 작업을 수행해야합니다. ' –

관련 문제